Marta Granero i Martí
#!pip install apafib --upgrade --user --quiet
#!pip install pandas==0.24.2 --upgrade --user
import apafib
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels as sm
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from sklearn.metrics import ConfusionMatrixDisplay,classification_report,\
RocCurveDisplay, PrecisionRecallDisplay,\
accuracy_score, f1_score, precision_score, recall_score
from sklearn.model_selection import cross_val_score
from sklearn import set_config
from sklearn.preprocessing import MinMaxScaler, StandardScaler, Binarizer
from sklearn.decomposition import PCA
from statsmodels.genmod.generalized_linear_model import GLM
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.naive_bayes import BernoulliNB, GaussianNB
from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.inspection import permutation_importance
from numpy.random import choice
from IPython.display import display, HTML #core.display deprecated
show_html = lambda html: display(HTML(html))
from yellowbrick.target.feature_correlation import feature_correlation
from yellowbrick.classifier import precision_recall_curve
from yellowbrick.classifier.rocauc import roc_auc
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
/Users/mac/Library/Python/3.10/lib/python/site-packages/statsmodels/tools/_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead. import pandas.util.testing as tm
En este problema experimentaremos con distintos clasificadores para ver la capacidad que tiene cada uno a la hora de predecir qué número cualsequiera de los que sigue, 4,7 o 9, es el dígito que se esconde detrás de la imagen codificada en 28x28 píxeles.
from apafib import load_MNIST
X_train, X_test, y_train, y_test = apafib.load_MNIST()
#X_train, X_test, y_train, y_test
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
X_train = pd.DataFrame(X_train, columns = np.arange(X_train.shape[1]))
X_test = pd.DataFrame(X_test, columns = np.arange(X_test.shape[1]))
#me guardo una copia del dataset de entrenamiento y test ya que mostraré los dígitos escritos a mano a partir
#del dataset y aplicaré transformaciones que modificaran ambos conjuntos
X_train_copia = X_train
X_test_copia = X_test
data_columns = X_train_copia.columns
data_columns = data_columns.values
#print(data_columns)
(4514, 784) (755, 784) (4514,) (755,)
Vemos que tanto el conjunto de datos de entrenamiento como el conjunto de test tienen 784 columnas, lo cuál nos indica que cada imagen esta compuesta por 784 píxeles, i.e 28x28 por imagen.
X_train.info(), X_test.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 4514 entries, 0 to 4513 Columns: 784 entries, 0 to 783 dtypes: float64(784) memory usage: 27.0 MB <class 'pandas.core.frame.DataFrame'> RangeIndex: 755 entries, 0 to 754 Columns: 784 entries, 0 to 783 dtypes: float64(784) memory usage: 4.5 MB
(None, None)
X_train.describe(include='all')
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 4514.0 | 4514.0 | 4514.0 | 4514.0 | 4514.0 | 4514.0 | 4514.0 | 4514.0 | 4514.0 | 4514.0 | ... | 4514.000000 | 4514.000000 | 4514.000000 | 4514.000000 | 4514.000000 | 4514.0 | 4514.0 | 4514.0 | 4514.0 | 4514.0 |
| mean | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | ... | 0.002261 | 0.000808 | 0.000657 | 0.000089 | 0.000134 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| std | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | ... | 0.040297 | 0.024357 | 0.022564 | 0.004127 | 0.008989 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| min | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | ... | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 25% | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | ... | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 50% | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | ... | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 75% | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | ... | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| max | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | ... | 0.992157 | 0.996078 | 0.992157 | 0.250980 | 0.603922 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
8 rows × 784 columns
exemples = dict(zip(list(y_train),[list(y_train).count(i) for i in list(y_train)]))
exemples
{4: 1426, 9: 1515, 7: 1573}
clases = [str(v) for v in sorted(np.unique(y_train))]
clases
['4', '7', '9']
X_train = X_train/255.0
X_test = X_test/255.0
X_train = X_train.values.reshape(-1, 28, 28, 1)
X_test = X_test.values.reshape(-1, 28, 28, 1)
num = 50
num_row = 10
num_col = 5
fig, axes = plt.subplots(num_row, num_col, figsize=(3*num_col,3*num_row))
for i in range(num):
ax = axes[i//num_col, i%num_col]
ax.imshow(X_train[:num][i], cmap='gray')
ax.set_title('Dígito: {}'.format(y_train[:num][i]))
plt.tight_layout()
plt.show()
X_train_standarized = X_train_copia.copy()
scaler = StandardScaler()
X_train_standarized[data_columns] = scaler.fit_transform(X_train_copia[data_columns])
X_train_standarized.describe().T
| count | mean | std | min | 25% | 50% | 75% | max | |
|---|---|---|---|---|---|---|---|---|
| 0 | 4514.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 1 | 4514.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 2 | 4514.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 3 | 4514.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 4 | 4514.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 779 | 4514.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 780 | 4514.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 781 | 4514.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 782 | 4514.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 783 | 4514.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
784 rows × 8 columns
X_test_standarized = X_test_copia.copy()
X_test_standarized[data_columns] = scaler.transform(X_test_copia[data_columns])
X_test_standarized.describe().T
| count | mean | std | min | 25% | 50% | 75% | max | |
|---|---|---|---|---|---|---|---|---|
| 0 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 1 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 2 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 3 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 4 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 779 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 780 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 781 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 782 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 783 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
784 rows × 8 columns
myPCA = PCA().fit(X_train_standarized[data_columns]);
#PCA.explained_variance_ratio_ para comprender qué porcentaje de varianza explican los datos
print(myPCA.explained_variance_ratio_)
print(myPCA.explained_variance_ratio_.cumsum())
[6.90543728e-02 5.24610875e-02 4.03322476e-02 3.23154847e-02 2.83870232e-02 2.27741208e-02 2.19071911e-02 1.96877134e-02 1.90347242e-02 1.71893389e-02 1.56047355e-02 1.45276514e-02 1.37900496e-02 1.32646032e-02 1.23999508e-02 1.21353348e-02 1.15890818e-02 1.10992701e-02 1.06358841e-02 1.03389630e-02 9.58733637e-03 9.51724367e-03 9.02038508e-03 8.83374746e-03 8.59362170e-03 8.37622194e-03 8.12496310e-03 8.02405822e-03 7.48142391e-03 7.42398565e-03 7.17928357e-03 6.79202219e-03 6.51528819e-03 6.38826900e-03 6.29264281e-03 6.21910693e-03 6.02283581e-03 5.80343608e-03 5.71887541e-03 5.52796377e-03 5.48432752e-03 5.31455740e-03 5.24147258e-03 5.16754080e-03 5.02292071e-03 4.89488740e-03 4.79032346e-03 4.76303608e-03 4.64443789e-03 4.53563728e-03 4.48379231e-03 4.39781845e-03 4.34107974e-03 4.26941348e-03 4.12585686e-03 4.09005431e-03 4.04515330e-03 3.92051719e-03 3.89486503e-03 3.83886034e-03 3.78988178e-03 3.72863791e-03 3.67036891e-03 3.65357775e-03 3.61454905e-03 3.60706356e-03 3.51787323e-03 3.44041669e-03 3.35384054e-03 3.28531189e-03 3.21462499e-03 3.20345570e-03 3.16849907e-03 3.13708874e-03 3.08096455e-03 3.05623947e-03 3.00969429e-03 2.96739168e-03 2.86780301e-03 2.86643609e-03 2.85242480e-03 2.81216410e-03 2.76752247e-03 2.72765191e-03 2.67117437e-03 2.63407542e-03 2.56174270e-03 2.53540088e-03 2.51293241e-03 2.49019005e-03 2.42591328e-03 2.41216289e-03 2.35105849e-03 2.32173783e-03 2.29624498e-03 2.28112244e-03 2.23829762e-03 2.17955468e-03 2.16476983e-03 2.14394100e-03 2.11923066e-03 2.09574991e-03 2.05256598e-03 2.03678197e-03 1.99818376e-03 1.98115230e-03 1.95811422e-03 1.92804413e-03 1.92483002e-03 1.88963022e-03 1.86528427e-03 1.84206549e-03 1.83690471e-03 1.80161345e-03 1.79174633e-03 1.75006257e-03 1.74229278e-03 1.72278756e-03 1.70485309e-03 1.69397141e-03 1.65645096e-03 1.64744394e-03 1.63202314e-03 1.61931372e-03 1.58791565e-03 1.56022702e-03 1.55198862e-03 1.54254904e-03 1.52054555e-03 1.51134530e-03 1.49866261e-03 1.46930392e-03 1.46295780e-03 1.44615961e-03 1.43738875e-03 1.40622691e-03 1.39219477e-03 1.35489838e-03 1.35045984e-03 1.32709962e-03 1.31024908e-03 1.30482284e-03 1.27631074e-03 1.27205918e-03 1.25937679e-03 1.23318114e-03 1.23048998e-03 1.20929329e-03 1.19585297e-03 1.18335716e-03 1.16883765e-03 1.15787229e-03 1.13933383e-03 1.12890799e-03 1.12057768e-03 1.10147457e-03 1.09365188e-03 1.06988825e-03 1.06644726e-03 1.04228482e-03 1.03563884e-03 1.03081844e-03 1.02193485e-03 9.96493794e-04 9.80062534e-04 9.70911006e-04 9.56170903e-04 9.52028855e-04 9.46690114e-04 9.32128806e-04 9.25661788e-04 9.20884996e-04 9.05723996e-04 8.94583931e-04 8.90331572e-04 8.80256175e-04 8.77317994e-04 8.52810484e-04 8.49862376e-04 8.25722334e-04 8.19945070e-04 8.14769833e-04 8.04800390e-04 7.97376860e-04 7.88746791e-04 7.77704848e-04 7.77196898e-04 7.59025211e-04 7.57308809e-04 7.48708326e-04 7.43251538e-04 7.29563095e-04 7.16601254e-04 7.05383977e-04 7.02056921e-04 6.97341051e-04 6.89006591e-04 6.83366334e-04 6.80308557e-04 6.71348710e-04 6.66897711e-04 6.58901623e-04 6.56599358e-04 6.51146801e-04 6.39215209e-04 6.29438424e-04 6.27421981e-04 6.16607333e-04 6.07349833e-04 5.97099497e-04 5.94838375e-04 5.89194030e-04 5.81705835e-04 5.76969787e-04 5.74791609e-04 5.68516992e-04 5.60685603e-04 5.53847807e-04 5.47179785e-04 5.41009880e-04 5.39713735e-04 5.32378430e-04 5.30769550e-04 5.19600683e-04 5.12222168e-04 5.07108022e-04 5.03448828e-04 5.01151351e-04 4.95934452e-04 4.91865070e-04 4.78806203e-04 4.76131146e-04 4.73615620e-04 4.64897792e-04 4.62977929e-04 4.58402883e-04 4.57036919e-04 4.51261791e-04 4.48097002e-04 4.40788166e-04 4.39455294e-04 4.37918226e-04 4.35392479e-04 4.29280355e-04 4.22862817e-04 4.20538109e-04 4.18415457e-04 4.16184006e-04 4.14618348e-04 4.08034429e-04 4.01818105e-04 3.97591187e-04 3.92852464e-04 3.89552903e-04 3.88147193e-04 3.86338114e-04 3.77295301e-04 3.73646501e-04 3.71047980e-04 3.69078852e-04 3.65203105e-04 3.64478802e-04 3.63551555e-04 3.58081827e-04 3.54880883e-04 3.49226616e-04 3.46742176e-04 3.41709358e-04 3.38586858e-04 3.35773944e-04 3.34075908e-04 3.30939656e-04 3.29230731e-04 3.27915971e-04 3.23465052e-04 3.20159158e-04 3.19348687e-04 3.13239417e-04 3.09486973e-04 3.09414012e-04 3.07085887e-04 3.03109465e-04 3.02195146e-04 3.00265411e-04 2.96750077e-04 2.95134797e-04 2.91035273e-04 2.89041823e-04 2.86325572e-04 2.83077601e-04 2.81774235e-04 2.77538295e-04 2.76453432e-04 2.74390318e-04 2.72048226e-04 2.71206062e-04 2.70892416e-04 2.68649328e-04 2.67156945e-04 2.65371135e-04 2.62728972e-04 2.59927196e-04 2.57711950e-04 2.55678440e-04 2.53268934e-04 2.48695557e-04 2.48152351e-04 2.45991482e-04 2.44515522e-04 2.43273417e-04 2.41296836e-04 2.38244301e-04 2.36130126e-04 2.34119399e-04 2.32296205e-04 2.30014281e-04 2.27689814e-04 2.27053658e-04 2.25018662e-04 2.22994644e-04 2.20627461e-04 2.19448792e-04 2.17797332e-04 2.17077899e-04 2.15329165e-04 2.11354280e-04 2.09072537e-04 2.07841151e-04 2.07068894e-04 2.04941560e-04 2.03663068e-04 2.01500179e-04 2.00529607e-04 1.98734783e-04 1.97406658e-04 1.96293459e-04 1.95006472e-04 1.92674064e-04 1.91433549e-04 1.88992562e-04 1.88605978e-04 1.87061876e-04 1.85638495e-04 1.83295979e-04 1.81262807e-04 1.81002271e-04 1.79711473e-04 1.78277847e-04 1.77955341e-04 1.76329684e-04 1.74117817e-04 1.71389586e-04 1.69840871e-04 1.68686643e-04 1.68014151e-04 1.67563062e-04 1.66564225e-04 1.65451109e-04 1.64280205e-04 1.63922950e-04 1.61392819e-04 1.59121508e-04 1.58865269e-04 1.57803003e-04 1.55116760e-04 1.54906662e-04 1.53465566e-04 1.52399475e-04 1.51951004e-04 1.50542392e-04 1.49035737e-04 1.48691438e-04 1.47835386e-04 1.46055036e-04 1.44687950e-04 1.44202545e-04 1.43443660e-04 1.41721927e-04 1.39809443e-04 1.39510114e-04 1.37960409e-04 1.37570655e-04 1.35843504e-04 1.34737135e-04 1.34192640e-04 1.33420775e-04 1.32455917e-04 1.31418104e-04 1.31172378e-04 1.30376990e-04 1.29515366e-04 1.29005934e-04 1.27338605e-04 1.26818787e-04 1.26009871e-04 1.24981442e-04 1.23839785e-04 1.23094659e-04 1.22533064e-04 1.20689096e-04 1.19816648e-04 1.19345155e-04 1.18023163e-04 1.16261518e-04 1.16098390e-04 1.15509047e-04 1.14182808e-04 1.13597042e-04 1.12399466e-04 1.11726738e-04 1.10895753e-04 1.10167278e-04 1.09651963e-04 1.08858133e-04 1.07735223e-04 1.07617329e-04 1.06728113e-04 1.05678296e-04 1.05100637e-04 1.04346320e-04 1.03922880e-04 1.02574716e-04 1.02074413e-04 1.01552441e-04 1.00568094e-04 1.00324774e-04 9.96410946e-05 9.89774334e-05 9.85634788e-05 9.79260630e-05 9.73317256e-05 9.62829231e-05 9.58243712e-05 9.49745065e-05 9.46403495e-05 9.36315897e-05 9.34803751e-05 9.18976879e-05 9.10154654e-05 9.03773639e-05 8.94075036e-05 8.85451813e-05 8.75662399e-05 8.74166824e-05 8.71665116e-05 8.67705136e-05 8.58939940e-05 8.53824232e-05 8.46653904e-05 8.43208638e-05 8.39012902e-05 8.34904001e-05 8.28503499e-05 8.19997950e-05 8.11478275e-05 8.07071677e-05 8.01804555e-05 7.97418157e-05 7.83857457e-05 7.78597939e-05 7.75149600e-05 7.66587885e-05 7.62107299e-05 7.58744723e-05 7.53860857e-05 7.47417890e-05 7.39716787e-05 7.36479799e-05 7.20497103e-05 7.18135030e-05 7.16569247e-05 7.08129516e-05 7.06280958e-05 6.98053126e-05 6.95414132e-05 6.93510374e-05 6.86795381e-05 6.81587470e-05 6.74826826e-05 6.70604564e-05 6.66998870e-05 6.64076020e-05 6.54939047e-05 6.52769002e-05 6.49778655e-05 6.39331821e-05 6.34106225e-05 6.27617483e-05 6.26513624e-05 6.21891321e-05 6.18000392e-05 6.07254395e-05 6.05968606e-05 5.96412810e-05 5.94175772e-05 5.91735357e-05 5.85854892e-05 5.77641583e-05 5.71171703e-05 5.68911984e-05 5.64490291e-05 5.63407895e-05 5.60489319e-05 5.52740692e-05 5.47580093e-05 5.36890640e-05 5.36303880e-05 5.32242017e-05 5.28144307e-05 5.23117782e-05 5.19176298e-05 5.18848751e-05 5.11731300e-05 5.08111165e-05 5.06025780e-05 5.03098209e-05 5.01236619e-05 4.97074258e-05 4.92177809e-05 4.86666301e-05 4.81283894e-05 4.73132826e-05 4.72221059e-05 4.69781482e-05 4.66838290e-05 4.64523021e-05 4.57707372e-05 4.55354957e-05 4.51428348e-05 4.47603455e-05 4.44460145e-05 4.38421624e-05 4.37158867e-05 4.31451022e-05 4.28902255e-05 4.27022811e-05 4.26297977e-05 4.16421340e-05 4.14623309e-05 4.12088953e-05 4.05136259e-05 4.01739778e-05 3.95388404e-05 3.90355685e-05 3.86801784e-05 3.80644655e-05 3.79655546e-05 3.75395277e-05 3.71921573e-05 3.69580434e-05 3.65981189e-05 3.62040434e-05 3.60400432e-05 3.53563978e-05 3.51061272e-05 3.47644661e-05 3.43996864e-05 3.38118310e-05 3.31070933e-05 3.30310676e-05 3.27599762e-05 3.21649265e-05 3.19344900e-05 3.15708695e-05 3.14620071e-05 3.09931169e-05 3.07393713e-05 3.03038169e-05 2.99261900e-05 2.95743874e-05 2.84375558e-05 2.83505414e-05 2.79796324e-05 2.73351988e-05 2.70456579e-05 2.63232691e-05 2.56413161e-05 2.51828258e-05 2.47309552e-05 2.43470772e-05 2.39031473e-05 2.33102346e-05 2.31247242e-05 2.20489047e-05 2.14178016e-05 2.04403249e-05 1.97641509e-05 1.76719246e-05 1.75466170e-05 1.65143600e-05 1.55565356e-05 1.44886408e-05 1.31901987e-05 1.21466442e-05 2.18532592e-06 6.36717607e-08 2.96193938e-31 6.39325037e-32 3.83933574e-32 3.13045456e-32 1.47968585e-32 4.92354301e-33 4.76983025e-33 4.73348616e-33 3.88918792e-33 3.47010735e-33 3.11880236e-33 2.83888324e-33 2.67255883e-33 2.48188245e-33 2.33053260e-33 2.29838816e-33 2.01195304e-33 1.84449379e-33 1.76141006e-33 1.73852105e-33 1.68234062e-33 1.62289543e-33 1.55153069e-33 1.49589201e-33 1.32466899e-33 1.26788037e-33 1.23631635e-33 1.01168977e-33 1.01079163e-33 9.70841333e-34 9.48904345e-34 8.71110358e-34 8.63271386e-34 8.14820266e-34 7.80746186e-34 7.36542138e-34 7.07678198e-34 6.70815076e-34 6.46834961e-34 5.58936420e-34 4.94357773e-34 4.58000136e-34 4.56491211e-34 4.40004989e-34 4.16145061e-34 3.97066147e-34 3.23183662e-34 2.92630075e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.64627725e-34 1.96488700e-34 1.58145054e-34 1.39273921e-34 1.27406130e-34 1.21823021e-34 1.06106397e-34 1.05244835e-34 8.87651695e-35 5.96562557e-35 5.36886788e-35 2.73703365e-35 1.12322463e-35 9.83938260e-36 1.60754684e-36] [0.06905437 0.12151546 0.16184771 0.19416319 0.22255022 0.24532434 0.26723153 0.28691924 0.30595397 0.3231433 0.33874804 0.35327569 0.36706574 0.38033034 0.39273029 0.40486563 0.41645471 0.42755398 0.43818987 0.44852883 0.45811616 0.46763341 0.47665379 0.48548754 0.49408116 0.50245738 0.51058235 0.51860641 0.52608783 0.53351182 0.5406911 0.54748312 0.55399841 0.56038668 0.56667932 0.57289843 0.57892126 0.5847247 0.59044358 0.59597154 0.60145587 0.60677042 0.6120119 0.61717944 0.62220236 0.62709725 0.63188757 0.63665061 0.64129504 0.64583068 0.65031447 0.65471229 0.65905337 0.66332278 0.66744864 0.6715387 0.67558385 0.67950437 0.68339923 0.68723809 0.69102797 0.69475661 0.69842698 0.70208056 0.70569511 0.70930217 0.71282004 0.71626046 0.7196143 0.72289961 0.72611424 0.72931769 0.73248619 0.73562328 0.73870425 0.74176049 0.74477018 0.74773757 0.75060537 0.75347181 0.75632424 0.7591364 0.76190392 0.76463157 0.76730275 0.76993682 0.77249857 0.77503397 0.7775469 0.78003709 0.782463 0.78487517 0.78722622 0.78954796 0.79184421 0.79412533 0.79636363 0.79854318 0.80070795 0.80285189 0.80497112 0.80706687 0.80911944 0.81115622 0.8131544 0.81513556 0.81709367 0.81902172 0.82094655 0.82283618 0.82470146 0.82654353 0.82838043 0.83018204 0.83197379 0.83372385 0.83546615 0.83718893 0.83889379 0.84058776 0.84224421 0.84389165 0.84552368 0.84714299 0.8487309 0.85029113 0.85184312 0.85338567 0.85490622 0.85641756 0.85791622 0.85938553 0.86084848 0.86229464 0.86373203 0.86513826 0.86653045 0.86788535 0.86923581 0.87056291 0.87187316 0.87317798 0.8744543 0.87572635 0.87698573 0.87821891 0.8794494 0.8806587 0.88185455 0.88303791 0.88420674 0.88536462 0.88650395 0.88763286 0.88875344 0.88985491 0.89094856 0.89201845 0.8930849 0.89412718 0.89516282 0.89619364 0.89721557 0.89821207 0.89919213 0.90016304 0.90111921 0.90207124 0.90301793 0.90395006 0.90487572 0.90579661 0.90670233 0.90759691 0.90848725 0.9093675 0.91024482 0.91109763 0.91194749 0.91277322 0.91359316 0.91440793 0.91521273 0.91601011 0.91679885 0.91757656 0.91835376 0.91911278 0.91987009 0.9206188 0.92136205 0.92209161 0.92280821 0.9235136 0.92421566 0.924913 0.925602 0.92628537 0.92696568 0.92763703 0.92830392 0.92896283 0.92961943 0.93027057 0.93090979 0.93153923 0.93216665 0.93278326 0.93339061 0.9339877 0.93458254 0.93517174 0.93575344 0.93633041 0.9369052 0.93747372 0.93803441 0.93858825 0.93913543 0.93967644 0.94021616 0.94074854 0.94127931 0.94179891 0.94231113 0.94281824 0.94332169 0.94382284 0.94431877 0.94481064 0.94528944 0.94576557 0.94623919 0.94670409 0.94716707 0.94762547 0.94808251 0.94853377 0.94898186 0.94942265 0.94986211 0.95030003 0.95073542 0.9511647 0.95158756 0.9520081 0.95242651 0.9528427 0.95325732 0.95366535 0.95406717 0.95446476 0.95485761 0.95524717 0.95563531 0.95602165 0.95639895 0.95677259 0.95714364 0.95751272 0.95787792 0.9582424 0.95860595 0.95896404 0.95931892 0.95966814 0.96001489 0.96035659 0.96069518 0.96103096 0.96136503 0.96169597 0.9620252 0.96235312 0.96267658 0.96299674 0.96331609 0.96362933 0.96393882 0.96424823 0.96455532 0.96485843 0.96516062 0.96546089 0.96575764 0.96605277 0.96634381 0.96663285 0.96691917 0.96720225 0.96748403 0.96776156 0.96803802 0.96831241 0.96858446 0.96885566 0.96912655 0.9693952 0.96966236 0.96992773 0.97019046 0.97045039 0.9707081 0.97096378 0.97121705 0.97146574 0.9717139 0.97195989 0.9722044 0.97244768 0.97268897 0.97292722 0.97316335 0.97339747 0.97362976 0.97385978 0.97408747 0.97431452 0.97453954 0.97476253 0.97498316 0.97520261 0.97542041 0.97563749 0.97585281 0.97606417 0.97627324 0.97648108 0.97668815 0.97689309 0.97709676 0.97729826 0.97749879 0.97769752 0.97789493 0.97809122 0.97828623 0.9784789 0.97867033 0.97885933 0.97904793 0.979235 0.97942063 0.97960393 0.97978519 0.97996619 0.98014591 0.98032418 0.98050214 0.98067847 0.98085259 0.98102398 0.98119382 0.9813625 0.98153052 0.98169808 0.98186465 0.9820301 0.98219438 0.9823583 0.98251969 0.98267881 0.98283768 0.98299548 0.9831506 0.98330551 0.98345897 0.98361137 0.98376332 0.98391386 0.9840629 0.98421159 0.98435943 0.98450548 0.98465017 0.98479437 0.98493782 0.98507954 0.98521935 0.98535886 0.98549682 0.98563439 0.98577023 0.98590497 0.98603916 0.98617258 0.98630504 0.98643646 0.98656763 0.98669801 0.98682752 0.98695653 0.98708387 0.98721068 0.98733669 0.98746168 0.98758552 0.98770861 0.98783114 0.98795183 0.98807165 0.98819099 0.98830902 0.98842528 0.98854138 0.98865689 0.98877107 0.98888467 0.98899707 0.98910879 0.98921969 0.98932986 0.98943951 0.98954837 0.9896561 0.98976372 0.98987045 0.98997612 0.99008123 0.99018557 0.99028949 0.99039207 0.99049414 0.9905957 0.99069626 0.99079659 0.99089623 0.99099521 0.99109377 0.9911917 0.99128903 0.99138531 0.99148114 0.99157611 0.99167075 0.99176438 0.99185786 0.99194976 0.99204078 0.99213115 0.99222056 0.99230911 0.99239667 0.99248409 0.99257126 0.99265803 0.99274392 0.9928293 0.99291397 0.99299829 0.99308219 0.99316568 0.99324853 0.99333053 0.99341168 0.99349239 0.99357257 0.99365231 0.99373069 0.99380855 0.99388607 0.99396273 0.99403894 0.99411481 0.9941902 0.99426494 0.99433891 0.99441256 0.99448461 0.99455642 0.99462808 0.99469889 0.99476952 0.99483933 0.99490887 0.99497822 0.9950469 0.99511506 0.99518254 0.9952496 0.9953163 0.99538271 0.9954482 0.99551348 0.99557846 0.99564239 0.9957058 0.99576856 0.99583121 0.9958934 0.9959552 0.99601593 0.99607652 0.99613617 0.99619558 0.99625476 0.99631334 0.99637111 0.99642822 0.99648512 0.99654156 0.9965979 0.99665395 0.99670923 0.99676399 0.99681768 0.99687131 0.99692453 0.99697734 0.99702966 0.99708157 0.99713346 0.99718463 0.99723544 0.99728605 0.99733635 0.99738648 0.99743619 0.9974854 0.99753407 0.9975822 0.99762951 0.99767673 0.99772371 0.9977704 0.99781685 0.99786262 0.99790815 0.9979533 0.99799806 0.9980425 0.99808635 0.99813006 0.99817321 0.9982161 0.9982588 0.99830143 0.99834307 0.99838453 0.99842574 0.99846626 0.99850643 0.99854597 0.998585 0.99862368 0.99866175 0.99869972 0.99873725 0.99877445 0.9988114 0.998848 0.99888421 0.99892025 0.9989556 0.99899071 0.99902547 0.99905987 0.99909369 0.99912679 0.99915982 0.99919258 0.99922475 0.99925668 0.99928825 0.99931972 0.99935071 0.99938145 0.99941175 0.99944168 0.99947125 0.99949969 0.99952804 0.99955602 0.99958336 0.9996104 0.99963672 0.99966237 0.99968755 0.99971228 0.99973663 0.99976053 0.99978384 0.99980696 0.99982901 0.99985043 0.99987087 0.99989064 0.99990831 0.99992585 0.99994237 0.99995793 0.99997241 0.9999856 0.99999775 0.99999994 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. ]
fig = plt.figure(figsize=(10,10));
plt.plot(range(1,len(myPCA.singular_values_ )+1),myPCA.singular_values_ ,alpha=0.8,marker='.');
#La nueva base son los vectores propios de la matriz de covarianza.
y_label = plt.ylabel('Vectores propios');
x_label = plt.xlabel('Componentes');
plt.title('Scree plot');
fig = plt.figure(figsize=(10,10));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
np.cumsum(myPCA.explained_variance_ratio_),
c='red',marker='.',
label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
Podemos ver que la variancia explicada acumulada pasa del 85% a partir del aproximadamente 125 componentes, las cien primeras componentes acumulan cerca del 80%. Podemos ver que a pesar del gran número de píxeles que tenemos, usamos relativamente pocos para explicar la varianza de los datos. Ya que una sexta parte de estos nos ayudan a describir más del 85% de la varianza.
Podemos ver que sí que existen correlaciones entre ciertos píxeles, ya que aparecen fuertes correlaciones entre algunas componentes, como se puede ver en el heatmap. Pero també se puede apreciar que no existen correlaciones entre la gran mayoria de estos.
fig, ax = plt.subplots(figsize=(100,50))
sns.heatmap(myPCA.components_, cmap='jet', xticklabels=list(X_train_standarized[X_train_copia.columns]), vmin=-np.max(np.abs(myPCA.components_)), vmax=np.max(np.abs(myPCA.components_)),ax=ax)
<AxesSubplot: >
transformed_train = myPCA.transform(X_train_standarized[X_train_copia.columns])
transformed_train
X_train_standarized[['PC1','PC2','PC3']] = transformed_train[:,:3]
fig = plt.figure(figsize=(8,8))
_ = sns.scatterplot(x='PC1', y='PC2', data=X_train_standarized, hue=y_train, palette='tab10')
import plotly.express as px
fig = px.scatter_3d(X_train_standarized, x='PC1', y='PC2', z='PC3',color=y_train)
fig.show()
La verdad és que la separación de clases que se puede ver no es del todo clara, ya que la separabilidad que hace de los tres es bastante confusa. Si que parece hacer casi un buen trabajo para el dígito 4 pero apenas queda muy clara la separación de clases entre los tres. Aunque empieza a intuirse un poco, como podemos ver el 7 queda rodeando al conjunto por el extremo izquierdo y debajo, seguido del dígito 9 más adentro y finalmente los datos que quedan más centrados que pertenecen a la clase del dígito 4. Aún así, parece que no ha terminado de agrupar bien los dígitos en función de su similitud y parace confundirse bastante.
También vemos bastantes valores outliers que son de la clase del 4 y 9 que se encuentran un poco alejados de donde se encuentran la mayoria de sus respectivos grupos de puntos. Seguramente han sido manuscritos con un formato poco convencional a lo que entendemos por la forma de escribir el 4 y 9. Además, podemos ver que sobretodo para las clases del 7 y 9 la separabilidad es confusa.
Por lo tanto, se ve claro que no podemos decir mucho acerca de la separabilidad y nos es difícil decir si todas son separables. Es por esto que más adelante probaremos a utilitzar el t-SNE para ver si podemos capturar las no linealidades que hay entre los píxeles.
Por ejemplo vemos como este 9 podría confundir al clasificador ya que parece un 4.
Por ejemplo vemos como este 7 podría confundir al clasificador ya que parece un 9 escrito muy rápido.
Este 4 un puede ser fácilmente distingido por cualquiera de nosotros, pero alomejor con la colocación de los píxeles podría confundir al clasificador diciendo que es un 9.
loadings = myPCA.components_.T * np.sqrt(myPCA.explained_variance_ratio_)
fig = px.scatter(X_train_standarized, x='PC1', y='PC2', color=y_train)
for i, feature in enumerate(X_train_copia.columns):
fig.add_shape(type='line',x0=0, y0=0,x1=loadings[i, 0],y1=loadings[i, 1])
fig.add_annotation(x=loadings[i, 0],y=loadings[i, 1],ax=0, ay=0,xanchor="center",yanchor="bottom",text=feature,)
fig.show()
from sklearn.manifold import TSNE
transformed_train = TSNE(n_components=2, perplexity=10, n_iter=2000, init='pca').fit_transform(X_train_standarized[data_columns])
fig = plt.figure(figsize=(8,8))
sns.scatterplot(x=transformed_train[:,0], y=transformed_train[:,1], hue=y_train, palette='tab10');
Esta es una clara visualización de la separabilidad entre clases que esperábamos ya que vemos un patrón de grupos claro auqnue también es cierto que tenemos pequeños grupos de distintas clases de dígitos que parecen agruparse debido a su parecido de escritura. Por lo tanto vemos que el conjunto de datos es ciertamente sencillo de clasificar correctamente al menos con los píxeles que tenemos. t-SNE nos ha podido capturar las no linealidades y nos muestra una clara separación de los tres dígitos.
lda = LinearDiscriminantAnalysis()
print(np.mean(cross_val_score(lda,X_train_copia,y_train,cv=10)))
0.9164800934010948
lda_model = LinearDiscriminantAnalysis().fit(X_train_copia, y_train)
coefs = pd.DataFrame(lda_model.coef_)
coefs.columns = data_columns
plt.figure(figsize=(100,20));
sns.heatmap(coefs.abs(), annot=True, linewidths=.5, cbar=True, xticklabels=True, cmap='jet', annot_kws={'size':12});
Podemos ver que ciertos píxeles tienen un peso importante en el modelo.
print(classification_report(lda_model.predict(X_test_copia), y_test))
precision recall f1-score support
4 0.90 0.94 0.92 239
7 0.91 0.94 0.92 241
9 0.92 0.85 0.88 275
accuracy 0.91 755
macro avg 0.91 0.91 0.91 755
weighted avg 0.91 0.91 0.91 755
Vemos que el acierto del modelo se correponde con el acierto que hemos visto en la validación cruzada.
Vemos que tenemos una precisión parecida en la clasificación de los tres dígitos. Aún así, tenemos un recall menor en la clase del 9 puesto que este tiene un menor porcentaje de predicciones positivas correctas en relación con el total de positivos reales.
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(lda_model, X_test_copia,y_test, ax=plt.subplot());
plt.figure(figsize=(8,8));
roc_auc(lda_model, X_train_copia, y_train, X_test_copia, y_test);
Vemos que para los dígitos 4 i 7 tenemos la misma AUC. Que divergen de la AUC del digito 9 en un 0.02. Podemos ver que aunque no tienen una AUC=1, tenemos casi, un clasificador con predicción perfecta. Es decir, para los tres dígitos la tasa de verdaderos positivos es 1 y la de falsos positivos es 0.
Ahora, a diferencia del modelo LDA, nuestro modelo de Naïve Bayes gausiano, asumirá que los píxeles son idependientes a diferencia del LDA. Esta implementación nos estimará una matriz de covarianzas independiente por cada etiqueta de clase: 4, 7, 9.
gnb = GaussianNB()
print(np.mean(cross_val_score(gnb,X_train_copia,y_train,cv=10)))
0.5919328728685518
Vemos que usando este modelo no tiene una buena precisión con respecto a la que habia obtenido LDA
gnb_model = GaussianNB().fit(X_train_copia, y_train)
print('Priors:', gnb_model.class_prior_)
print('Means:')
means = pd.DataFrame(gnb_model.theta_)
means.columns= data_columns
means
Priors: [0.31590607 0.34847142 0.33562251] Means:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ... | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | ... | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 1 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | ... | 0.005916 | 0.001668 | 0.001177 | 0.000160 | 0.000000 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 2 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | ... | 0.000593 | 0.000676 | 0.000735 | 0.000101 | 0.000399 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
3 rows × 784 columns
print(classification_report(gnb_model.predict(X_test_copia), y_test))
precision recall f1-score support
4 0.43 0.92 0.59 118
7 0.29 0.90 0.44 80
9 0.97 0.45 0.61 557
accuracy 0.57 755
macro avg 0.56 0.75 0.54 755
weighted avg 0.82 0.57 0.59 755
El acierto con el conjunto de test es parecido al de validación cruzada, y dos de las tres clases no tienen unos valores demasiado buenos, donde la clase del dígito 7 parece la peor de todas.
Vemos que este modelo desbalancea mas la precisión de cada clase, con un acierto peor para la clase 4 y 7.
Tenemos dos situaciones que se nos estan dando:
Con la clase del 4 y 7 tenemos un alto recall pero una baja precision lo que significa es que devuelve muchos resultados, pero la mayoría de sus etiquetas predichas son incorrectas en comparación con las etiquetas de entrenamiento.
Con la clase del 9 tenemos una alta precision pero poco recall lo que es todo lo contrario, arroja muy pocos resultados, pero la mayoría de sus etiquetas predichas son correctas en comparación con las etiquetas de entrenamiento.
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(gnb_model, X_test_copia, y_test, display_labels=clases, ax=plt.subplot());
La curva ROC con más de dos clases nos muestra la tasa de $\frac{verdaderos positivos}{falsos positivos}$ de una clase respecto al resto y una media/media ponderada.
plt.figure(figsize=(8,8));
roc_auc(gnb_model, X_train_copia, y_train, X_test_copia, y_test);
Podemos ver que las AUC del dígito 9 no es demadiaso buena tal y como podíamos esperar con un alto porcentaje de falsos positivos, por otro lado la AUC de las clases 4 y 7 es mejor.
X_train_bin = Binarizer(threshold=0.5).transform(X_train_copia)
X_test_bin = Binarizer(threshold=0.5).transform(X_test_copia)
X_train_bin.shape, X_test_bin.shape
((4514, 784), (755, 784))
X_train_bin = pd.DataFrame(X_train_bin)
X_test_bin = pd.DataFrame(X_test_bin)
X_train_bin.shape, X_test_bin.shape
X_train_bin_2 = X_train_bin.copy()
myPCA = PCA().fit(X_train_bin[data_columns]);
#PCA.explained_variance_ratio_ para comprender qué porcentaje de varianza explican los datos
print(myPCA.explained_variance_ratio_)
print(myPCA.explained_variance_ratio_.cumsum())
X_train_bin.shape, X_test_bin.shape
[9.86798398e-02 7.04159474e-02 6.36020040e-02 5.31339161e-02 3.52681806e-02 3.22573620e-02 2.92687983e-02 2.81081504e-02 2.39018796e-02 2.16883416e-02 2.00622161e-02 1.80625948e-02 1.71227051e-02 1.48541649e-02 1.27857931e-02 1.22601056e-02 1.08417855e-02 1.04941546e-02 1.01347878e-02 8.92418783e-03 8.42672796e-03 8.39248180e-03 7.92445291e-03 7.67216304e-03 7.26547858e-03 6.76383979e-03 6.59597574e-03 6.32187391e-03 5.93263536e-03 5.90091617e-03 5.56263645e-03 5.30204256e-03 5.12971018e-03 4.85244121e-03 4.75997704e-03 4.61781320e-03 4.41360918e-03 4.37273155e-03 4.06526852e-03 3.95588871e-03 3.81041156e-03 3.74375705e-03 3.66060359e-03 3.52344667e-03 3.49995732e-03 3.31201567e-03 3.15033722e-03 3.11434482e-03 3.02280040e-03 2.98051696e-03 2.84618846e-03 2.78909934e-03 2.74665561e-03 2.71329826e-03 2.61310964e-03 2.59562078e-03 2.55321005e-03 2.52241692e-03 2.47551531e-03 2.41137283e-03 2.37521385e-03 2.28800414e-03 2.24981956e-03 2.19382900e-03 2.16139375e-03 2.14203895e-03 2.11876075e-03 2.09488626e-03 2.04760584e-03 2.02373766e-03 1.98127750e-03 1.92705662e-03 1.90018920e-03 1.86134698e-03 1.85379294e-03 1.83663645e-03 1.82205620e-03 1.78287565e-03 1.77113778e-03 1.74660904e-03 1.72013074e-03 1.70774423e-03 1.67188255e-03 1.64253119e-03 1.62566053e-03 1.60717981e-03 1.58540266e-03 1.57384066e-03 1.56113555e-03 1.54271278e-03 1.52758166e-03 1.50891465e-03 1.47906087e-03 1.45207754e-03 1.42431058e-03 1.41221494e-03 1.40669552e-03 1.38816917e-03 1.36743791e-03 1.35985192e-03 1.34537646e-03 1.33413717e-03 1.31796140e-03 1.31145211e-03 1.30437260e-03 1.29486502e-03 1.28165518e-03 1.27678099e-03 1.25415287e-03 1.23507083e-03 1.22088650e-03 1.20770298e-03 1.20491738e-03 1.20306865e-03 1.18048109e-03 1.17629956e-03 1.16734655e-03 1.15378401e-03 1.15194593e-03 1.13981288e-03 1.13078954e-03 1.11674440e-03 1.11069671e-03 1.10134205e-03 1.08972615e-03 1.07777265e-03 1.07066318e-03 1.06349559e-03 1.05719198e-03 1.04944405e-03 1.04042456e-03 1.03573069e-03 1.03074442e-03 1.02091352e-03 1.01608538e-03 1.00900307e-03 9.98746368e-04 9.88304753e-04 9.84607681e-04 9.71511141e-04 9.62230990e-04 9.58754218e-04 9.55635643e-04 9.47094852e-04 9.41108245e-04 9.35137075e-04 9.25800262e-04 9.21307613e-04 9.09499199e-04 8.97888146e-04 8.94400181e-04 8.87746524e-04 8.83773471e-04 8.76684104e-04 8.68235669e-04 8.62673790e-04 8.55291458e-04 8.50009733e-04 8.45057473e-04 8.41253158e-04 8.31717885e-04 8.27100045e-04 8.25614454e-04 8.15480878e-04 8.14286513e-04 8.05906104e-04 8.00796688e-04 7.96109391e-04 7.94519796e-04 7.85594602e-04 7.82977209e-04 7.79700148e-04 7.76711828e-04 7.65885923e-04 7.63033953e-04 7.58816942e-04 7.54659364e-04 7.44889572e-04 7.37053808e-04 7.33610340e-04 7.30261998e-04 7.25011430e-04 7.20200103e-04 7.15815206e-04 7.08858203e-04 7.05746267e-04 7.03524279e-04 7.00395356e-04 6.95550428e-04 6.91398213e-04 6.87295558e-04 6.83692415e-04 6.76950689e-04 6.69072701e-04 6.65939212e-04 6.62761454e-04 6.60020653e-04 6.59435212e-04 6.46938361e-04 6.45511470e-04 6.43407399e-04 6.36852592e-04 6.32326600e-04 6.29064424e-04 6.24932086e-04 6.21071727e-04 6.14941311e-04 6.12668854e-04 6.10835455e-04 6.03096616e-04 5.99910316e-04 5.96380621e-04 5.93975497e-04 5.90131016e-04 5.85771507e-04 5.80926022e-04 5.75120492e-04 5.71561237e-04 5.67441902e-04 5.61100253e-04 5.57855464e-04 5.53285354e-04 5.49820453e-04 5.47781751e-04 5.42649063e-04 5.38337605e-04 5.35100002e-04 5.31700401e-04 5.22781947e-04 5.21881014e-04 5.14738914e-04 5.14217712e-04 5.09661825e-04 5.03586191e-04 4.99509339e-04 4.94909433e-04 4.90163577e-04 4.88464119e-04 4.84587062e-04 4.82223654e-04 4.80513044e-04 4.76291574e-04 4.69242905e-04 4.65049603e-04 4.62839502e-04 4.60928268e-04 4.58550521e-04 4.52943767e-04 4.49041719e-04 4.45190543e-04 4.41593561e-04 4.41096751e-04 4.38877024e-04 4.34621049e-04 4.31043083e-04 4.26431344e-04 4.22481408e-04 4.20759511e-04 4.19086833e-04 4.14392809e-04 4.12367475e-04 4.11452647e-04 4.02959512e-04 4.01350053e-04 3.99864877e-04 3.97326418e-04 3.93804489e-04 3.89925146e-04 3.86694479e-04 3.82654222e-04 3.80257242e-04 3.76516964e-04 3.72924242e-04 3.70684400e-04 3.68154395e-04 3.63851409e-04 3.61565063e-04 3.59963610e-04 3.55215555e-04 3.51211804e-04 3.46752540e-04 3.43744340e-04 3.40998336e-04 3.39686347e-04 3.31673591e-04 3.29525289e-04 3.25993664e-04 3.24733500e-04 3.22226523e-04 3.20443816e-04 3.16299551e-04 3.14485477e-04 3.08342379e-04 3.04034344e-04 2.99029148e-04 2.97796746e-04 2.96375830e-04 2.92736001e-04 2.91812454e-04 2.86393214e-04 2.84505154e-04 2.80889512e-04 2.78772619e-04 2.76958587e-04 2.74852838e-04 2.72564847e-04 2.68150468e-04 2.63407197e-04 2.60589752e-04 2.57453959e-04 2.56233766e-04 2.53213954e-04 2.50362918e-04 2.46603739e-04 2.43228465e-04 2.41414425e-04 2.39541979e-04 2.36901331e-04 2.32609357e-04 2.31961344e-04 2.28438285e-04 2.24517386e-04 2.22968118e-04 2.18678509e-04 2.14969009e-04 2.14144381e-04 2.11991428e-04 2.09808964e-04 2.06169803e-04 2.03263299e-04 2.00161172e-04 1.97690155e-04 1.96313561e-04 1.92906123e-04 1.91316689e-04 1.89201981e-04 1.86818593e-04 1.83459887e-04 1.82419298e-04 1.80549411e-04 1.77993216e-04 1.75093863e-04 1.70763435e-04 1.69372391e-04 1.66622832e-04 1.61761122e-04 1.61115293e-04 1.59300549e-04 1.57434929e-04 1.55936605e-04 1.55273682e-04 1.54205401e-04 1.52421389e-04 1.50806017e-04 1.48238961e-04 1.46391244e-04 1.44028162e-04 1.42212403e-04 1.41223272e-04 1.37246426e-04 1.36308794e-04 1.34671823e-04 1.33080656e-04 1.32465076e-04 1.30329486e-04 1.26506833e-04 1.24942744e-04 1.23617101e-04 1.22373191e-04 1.21344186e-04 1.18966008e-04 1.17825607e-04 1.16129981e-04 1.13816623e-04 1.12067828e-04 1.11389139e-04 1.10624665e-04 1.09465208e-04 1.08523646e-04 1.05962625e-04 1.04902058e-04 1.03308464e-04 1.00360259e-04 9.96922125e-05 9.81542680e-05 9.65107590e-05 9.63001216e-05 9.51725187e-05 9.36350641e-05 9.02760938e-05 9.01417386e-05 8.96320984e-05 8.71310962e-05 8.67546496e-05 8.51812901e-05 8.26372461e-05 8.15129991e-05 8.06371423e-05 7.85563545e-05 7.72131947e-05 7.70403713e-05 7.63940619e-05 7.46662773e-05 7.20446998e-05 7.02455412e-05 6.93631234e-05 6.86414049e-05 6.73050980e-05 6.63883691e-05 6.51019853e-05 6.42237218e-05 6.35940616e-05 6.27659536e-05 6.22173437e-05 6.14951949e-05 5.97647363e-05 5.91207376e-05 5.84643300e-05 5.74801057e-05 5.67875485e-05 5.63392551e-05 5.50444872e-05 5.41714096e-05 5.26620173e-05 5.19051757e-05 5.17649695e-05 5.02842806e-05 4.98319165e-05 4.95129501e-05 4.89616906e-05 4.72960705e-05 4.66765970e-05 4.58199825e-05 4.46250585e-05 4.44306841e-05 4.28951952e-05 4.21669020e-05 4.20280791e-05 3.97174154e-05 3.96513451e-05 3.83120521e-05 3.80815504e-05 3.71227003e-05 3.67371472e-05 3.65751940e-05 3.55179813e-05 3.51512148e-05 3.47859768e-05 3.42312849e-05 3.35412594e-05 3.32326056e-05 3.22203835e-05 3.21044284e-05 3.15462175e-05 3.10160189e-05 3.04694549e-05 2.97913575e-05 2.94674543e-05 2.91453011e-05 2.78808043e-05 2.77236068e-05 2.72665793e-05 2.68379427e-05 2.62597852e-05 2.55039548e-05 2.51671971e-05 2.47633887e-05 2.40094533e-05 2.34012481e-05 2.27479373e-05 2.26812987e-05 2.20862148e-05 2.11492952e-05 2.05902495e-05 2.01656202e-05 2.01195572e-05 1.94797566e-05 1.93270485e-05 1.87820724e-05 1.86516371e-05 1.84468542e-05 1.79176149e-05 1.76865882e-05 1.66458325e-05 1.61443651e-05 1.59074920e-05 1.52864376e-05 1.51998708e-05 1.51827973e-05 1.48990285e-05 1.46495099e-05 1.41370327e-05 1.39017144e-05 1.38153532e-05 1.30943254e-05 1.27843340e-05 1.22953110e-05 1.18195252e-05 1.15811754e-05 1.13010252e-05 1.09883982e-05 1.04959232e-05 1.04750745e-05 1.01876689e-05 9.94403235e-06 9.70976490e-06 9.43689191e-06 9.33290900e-06 9.10932240e-06 8.78696455e-06 8.69260515e-06 8.33673784e-06 8.21084539e-06 8.13849900e-06 7.95688455e-06 7.65345549e-06 7.18026630e-06 6.91811800e-06 6.75946574e-06 6.67847134e-06 6.60827899e-06 6.31919071e-06 5.95416943e-06 5.74707056e-06 5.56694711e-06 5.39032235e-06 5.21366606e-06 5.19893354e-06 4.95223472e-06 4.76708093e-06 4.50989051e-06 4.46797500e-06 4.26204159e-06 4.18115481e-06 4.15701256e-06 3.98835822e-06 3.77539879e-06 3.56581890e-06 3.53663832e-06 3.21958550e-06 3.10378880e-06 3.05684819e-06 3.02621799e-06 2.73889694e-06 2.69730203e-06 2.66023779e-06 2.51080690e-06 2.45319987e-06 2.38420955e-06 2.25307503e-06 2.03850701e-06 1.96147857e-06 1.84674802e-06 1.60566854e-06 1.42747044e-06 1.35808602e-06 1.23842396e-06 1.21138234e-06 1.15899041e-06 1.12118114e-06 9.64891887e-07 8.53512378e-07 8.32853898e-07 7.75026313e-07 7.63510748e-07 6.22234458e-07 4.24219140e-07 3.45987888e-07 3.28079315e-07 1.96049565e-32 6.47531246e-33 5.16192985e-33 4.68768237e-33 4.06556242e-33 4.01784362e-33 3.66222022e-33 3.09073295e-33 2.61804802e-33 2.47990181e-33 2.37282080e-33 2.10301805e-33 1.94897094e-33 1.79492023e-33 1.77076194e-33 1.51853461e-33 1.45629031e-33 1.23013282e-33 1.20454342e-33 9.80313193e-34 7.00500055e-34 6.84576105e-34 6.56904073e-34 4.44176191e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 3.35166108e-34 3.11518758e-34 2.98493256e-34 2.73285252e-34 1.50036002e-34 8.98153107e-35 5.87713160e-35 2.79741894e-35 4.23372289e-36] [0.09867984 0.16909579 0.23269779 0.28583171 0.32109989 0.35335725 0.38262605 0.4107342 0.43463608 0.45632442 0.47638664 0.49444923 0.51157194 0.5264261 0.53921189 0.551472 0.56231378 0.57280794 0.58294273 0.59186692 0.60029364 0.60868612 0.61661058 0.62428274 0.63154822 0.63831206 0.64490803 0.65122991 0.65716254 0.66306346 0.6686261 0.67392814 0.67905785 0.68391029 0.68867027 0.69328808 0.69770169 0.70207442 0.70613969 0.71009558 0.71390599 0.71764975 0.72131035 0.7248338 0.72833376 0.73164577 0.73479611 0.73791045 0.74093325 0.74391377 0.74675996 0.74954906 0.75229571 0.75500901 0.75762212 0.76021774 0.76277095 0.76529337 0.76776888 0.77018026 0.77255547 0.77484348 0.77709329 0.77928712 0.78144852 0.78359056 0.78570932 0.7878042 0.78985181 0.79187555 0.79385682 0.79578388 0.79768407 0.79954542 0.80139921 0.80323585 0.8050579 0.80684078 0.80861192 0.81035853 0.81207866 0.8137864 0.81545828 0.81710081 0.81872647 0.82033365 0.82191906 0.8234929 0.82505403 0.82659675 0.82812433 0.82963324 0.8311123 0.83256438 0.83398869 0.83540091 0.8368076 0.83819577 0.83956321 0.84092306 0.84226844 0.84360257 0.84492054 0.84623199 0.84753636 0.84883123 0.85011288 0.85138966 0.85264381 0.85387889 0.85509977 0.85630748 0.85751239 0.85871546 0.85989594 0.86107224 0.86223959 0.86339337 0.86454532 0.86568513 0.86681592 0.86793267 0.86904336 0.8701447 0.87123443 0.8723122 0.87338287 0.87444636 0.87550355 0.876553 0.87759342 0.87862915 0.8796599 0.88068081 0.8816969 0.8827059 0.88370465 0.88469295 0.88567756 0.88664907 0.8876113 0.88857005 0.88952569 0.89047278 0.89141389 0.89234903 0.89327483 0.89419614 0.89510564 0.89600353 0.89689793 0.89778567 0.89866945 0.89954613 0.90041437 0.90127704 0.90213233 0.90298234 0.9038274 0.90466865 0.90550037 0.90632747 0.90715308 0.90796856 0.90878285 0.90958876 0.91038955 0.91118566 0.91198018 0.91276578 0.91354875 0.91432845 0.91510517 0.91587105 0.91663409 0.9173929 0.91814756 0.91889245 0.91962951 0.92036312 0.92109338 0.92181839 0.92253859 0.92325441 0.92396326 0.92466901 0.92537253 0.92607293 0.92676848 0.92745988 0.92814717 0.92883087 0.92950782 0.93017689 0.93084283 0.93150559 0.93216561 0.93282505 0.93347198 0.9341175 0.9347609 0.93539776 0.93603008 0.93665915 0.93728408 0.93790515 0.93852009 0.93913276 0.9397436 0.94034669 0.9409466 0.94154298 0.94213696 0.94272709 0.94331286 0.94389379 0.94446891 0.94504047 0.94560791 0.94616901 0.94672687 0.94728015 0.94782997 0.94837775 0.9489204 0.94945874 0.94999384 0.95052554 0.95104832 0.9515702 0.95208494 0.95259916 0.95310882 0.95361241 0.95411192 0.95460683 0.95509699 0.95558546 0.95607004 0.95655227 0.95703278 0.95750907 0.95797831 0.95844336 0.9589062 0.95936713 0.95982568 0.96027863 0.96072767 0.96117286 0.96161445 0.96205555 0.96249443 0.96292905 0.96336009 0.96378652 0.964209 0.96462976 0.96504885 0.96546324 0.96587561 0.96628706 0.96669002 0.96709137 0.96749124 0.96788856 0.96828237 0.96867229 0.96905899 0.96944164 0.9698219 0.97019841 0.97057134 0.97094202 0.97131018 0.97167403 0.97203559 0.97239556 0.97275077 0.97310199 0.97344874 0.97379248 0.97413348 0.97447317 0.97480484 0.97513437 0.97546036 0.97578509 0.97610732 0.97642776 0.97674406 0.97705855 0.97736689 0.97767092 0.97796995 0.97826775 0.97856413 0.97885686 0.97914868 0.97943507 0.97971957 0.98000046 0.98027924 0.98055619 0.98083105 0.98110361 0.98137176 0.98163517 0.98189576 0.98215321 0.98240945 0.98266266 0.98291302 0.98315963 0.98340286 0.98364427 0.98388381 0.98412071 0.98435332 0.98458528 0.98481372 0.98503824 0.98526121 0.98547989 0.98569486 0.985909 0.98612099 0.9863308 0.98653697 0.98674023 0.98694039 0.98713808 0.9873344 0.9875273 0.98771862 0.98790782 0.98809464 0.9882781 0.98846052 0.98864107 0.98881906 0.98899416 0.98916492 0.98933429 0.98950092 0.98966268 0.98982379 0.98998309 0.99014053 0.99029646 0.99045174 0.99060594 0.99075837 0.99090917 0.99105741 0.9912038 0.99134783 0.99149004 0.99163127 0.99176851 0.99190482 0.99203949 0.99217257 0.99230504 0.99243537 0.99256187 0.99268682 0.99281043 0.99293281 0.99305415 0.99317312 0.99329094 0.99340707 0.99352089 0.99363296 0.99374435 0.99385497 0.99396444 0.99407296 0.99417892 0.99428382 0.99438713 0.99448749 0.99458719 0.99468534 0.99478185 0.99487815 0.99497332 0.99506696 0.99515723 0.99524738 0.99533701 0.99542414 0.99551089 0.99559608 0.99567871 0.99576023 0.99584086 0.99591942 0.99599663 0.99607367 0.99615007 0.99622473 0.99629678 0.99636702 0.99643639 0.99650503 0.99657233 0.99663872 0.99670382 0.99676805 0.99683164 0.99689441 0.99695662 0.99701812 0.99707788 0.99713701 0.99719547 0.99725295 0.99730974 0.99736608 0.99742112 0.99747529 0.99752795 0.99757986 0.99763162 0.99768191 0.99773174 0.99778125 0.99783022 0.99787751 0.99792419 0.99797001 0.99801463 0.99805906 0.99810196 0.99814413 0.99818615 0.99822587 0.99826552 0.99830383 0.99834192 0.99837904 0.99841578 0.99845235 0.99848787 0.99852302 0.99855781 0.99859204 0.99862558 0.99865881 0.99869103 0.99872314 0.99875468 0.9987857 0.99881617 0.99884596 0.99887543 0.99890457 0.99893245 0.99896018 0.99898744 0.99901428 0.99904054 0.99906604 0.99909121 0.99911598 0.99913998 0.99916339 0.99918613 0.99920882 0.9992309 0.99925205 0.99927264 0.99929281 0.99931293 0.99933241 0.99935173 0.99937052 0.99938917 0.99940761 0.99942553 0.99944322 0.99945986 0.99947601 0.99949192 0.9995072 0.9995224 0.99953758 0.99955248 0.99956713 0.99958127 0.99959517 0.99960899 0.99962208 0.99963487 0.99964716 0.99965898 0.99967056 0.99968186 0.99969285 0.99970335 0.99971382 0.99972401 0.99973395 0.99974366 0.9997531 0.99976243 0.99977154 0.99978033 0.99978902 0.99979736 0.99980557 0.99981371 0.99982167 0.99982932 0.9998365 0.99984342 0.99985018 0.99985686 0.99986346 0.99986978 0.99987574 0.99988148 0.99988705 0.99989244 0.99989766 0.99990285 0.99990781 0.99991257 0.99991708 0.99992155 0.99992581 0.99992999 0.99993415 0.99993814 0.99994192 0.99994548 0.99994902 0.99995224 0.99995534 0.9999584 0.99996142 0.99996416 0.99996686 0.99996952 0.99997203 0.99997448 0.99997687 0.99997912 0.99998116 0.99998312 0.99998497 0.99998657 0.999988 0.99998936 0.9999906 0.99999181 0.99999297 0.99999409 0.99999505 0.99999591 0.99999674 0.99999752 0.99999828 0.9999989 0.99999933 0.99999967 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. ]
((4514, 784), (755, 784))
fig = plt.figure(figsize=(10,10));
plt.plot(range(1,len(myPCA.singular_values_ )+1),myPCA.singular_values_ ,alpha=0.8,marker='.');
#La nueva base son los vectores propios de la matriz de covarianza.
y_label = plt.ylabel('Vectores propios');
x_label = plt.xlabel('Componentes');
plt.title('Scree plot');
X_train_bin.shape, X_test_bin.shape
((4514, 784), (755, 784))
fig = plt.figure(figsize=(8,6));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
np.cumsum(myPCA.explained_variance_ratio_),
c='red',marker='.',
label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
X_train_bin.shape, X_test_bin.shape
((4514, 784), (755, 784))
Podemos ver que la variancia explicada acumulada pasa del 85% a partir del aproximadamente 90/95 componentes, las primeras cincuenta componentes acumulan cerca del 75%. Podemos ver que a pesar del gran número de píxeles que tenemos, ahora con repecto al mismo plot que hemos hecho antes, binarizando la matriz de datos podemos ver una ligera mejora y una mayor explicabilidad de la varianza de los datos con menos componentes.
fig, ax = plt.subplots(figsize=(100,50))
sns.heatmap(myPCA.components_, cmap='jet', xticklabels=list(X_train_bin[X_train_copia.columns]), vmin=-np.max(np.abs(myPCA.components_)), vmax=np.max(np.abs(myPCA.components_)),ax=ax)
X_train_bin.shape, X_test_bin.shape
((4514, 784), (755, 784))
transformed_train = myPCA.transform(X_train_bin_2[X_train_copia.columns])
transformed_train
X_train_bin_2[['PC1','PC2','PC3']] = transformed_train[:,:3]
fig = plt.figure(figsize=(8,8))
_ = sns.scatterplot(x='PC1', y='PC2', data=X_train_bin_2, hue=y_train, palette='tab10')
Se puede empezar a ver una mejor separabilidad de las clases, ahora las clases del dígito 7 y 9 no estan tan juntas como antes. Aún así, vemos que tenemos la mayoria de los datos siguen sin agruparse de forma correcta.
import plotly.express as px
fig = px.scatter_3d(X_train_bin_2, x='PC1', y='PC2', z='PC3',color=y_train)
fig.show()
No podemos apreciar una buena separabilidad entre clases con estas dos componentes aunque los datos estan más dispersos con respecto al PCA con la matriz sin binarizar. Ante esta situación podemos volver a realizar un t-SNE para ver si realmente se puede ver una mejora en la separabilidad.
loadings = myPCA.components_.T * np.sqrt(myPCA.explained_variance_ratio_)
fig = px.scatter(X_train_bin_2, x='PC1', y='PC2', color=y_train)
for i, feature in enumerate(X_train_copia.columns):
fig.add_shape(type='line',x0=0, y0=0,x1=loadings[i, 0],y1=loadings[i, 1])
fig.add_annotation(x=loadings[i, 0],y=loadings[i, 1],ax=0, ay=0,xanchor="center",yanchor="bottom",text=feature,)
fig.show()
from sklearn.manifold import TSNE
transformed_train = TSNE(n_components=2, perplexity=10, n_iter=2000, init='pca').fit_transform(X_train_bin_2[data_columns])
fig = plt.figure(figsize=(8,8))
sns.scatterplot(x=transformed_train[:,0], y=transformed_train[:,1], hue=y_train, palette='tab10');
Tenemos una mejor visualización de la separabilidad entre clases y también vemos un patrón de grupos claro. Además con repecto al mismo plot que teníamos antes vemos que se han reducido el número de pequeños grupos de distintas clases de dígitos que se agrupan en clases que no son las suyas, puesto que distintos ejemplos de varias clases tienen un parecido de escritura.
Vemos que igualmente el conjunto de datos es ciertamente sencillo de clasificar correctamente al menos con los píxeles que tenemos.
Parece que podríamos decir que este problema tiende a parecer que tiene cierta naturaleza no lineal
bnb = BernoulliNB()
print(np.mean(cross_val_score(bnb, X_train_bin, y_train, cv=10)))
0.8593249023801581
Vemos que obtenemos un mejor error de validación cruzada con respecto al modelo de Naïve Bayes Gausiano pero no tan bueno como al que habíamos obtenido para el LDA.
bnb_model = BernoulliNB().fit(X_train_bin, y_train)
print(classification_report(bnb_model.predict(X_test_bin), y_test, target_names=clases))
precision recall f1-score support
4 0.82 0.89 0.86 231
7 0.88 0.92 0.90 238
9 0.87 0.78 0.82 286
accuracy 0.86 755
macro avg 0.86 0.87 0.86 755
weighted avg 0.86 0.86 0.86 755
El acierto con el conjunto de test es parecido al de validación cruzada y ahora todas las clases tiene unos valores buenos y sin desbalances notables en la precisión como sucedia antes con el modelo de NB gausiano. Aún así, otra vez, la clase del dígito 9 sigue siendo la peor de todas con respecto al recall que obtiene.
Cabe destacar que ahora la clase que obtiene mejor precision es la del 7, además esta también tiene el mejor recall, lo que nos indica que realiza una muy buena clasificación de esta clase.
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(bnb_model, X_test_bin, y_test, display_labels=clases, ax=plt.subplot());
plt.figure(figsize=(8,8));
roc_auc(bnb_model, X_train_bin, y_train, X_test_bin, y_test);
Vemos que ahora las tres AUC tienen un valor parecido, la mejor siendo la del 7 seguida de la del 4. Vemos que la curva ROC de la clase del 7 tiene la mejor tasa de $\frac{verdaderos positivos}{falsos positivos}$ respecto al resto.
Vemos que realmente este modelo último de NB Bernoulli es mejor que el modelo de NB Gausiano puesto que obtenemos un mejor error con el conjunto de test, ya que pasamos de una precision del *0.57* con el conjunto de test del NB Gausiano a una accuracy del *0.86* con el modelo del NB Bernoulli. Vemos que ambos errores del conjunto de test tienen un acierto parecido al de validación cruzada.
Cabe notar que la AUC de los dígitos 4,7 no ha mejorado notablemente, puesto que con el modelo de *NBG* habíamos obtenido unos valors del 0.93 y 0.94 y ahora unos valores del 0.97 y 0.98 esto se debe a que ahora tenemos una precision mayor pero un recall parecido al que ya teníamos con el modelo de *NBG* y además ha mejorado la media/media ponderada
El AUC del dígito 9 ahora si que ha mejorado ya que, hemos pasado de una AUC=0.68 a una AUC del 0.95 con un mayor recall ahora sí.
Es importate que todos los atributos se encuenten en la misma escala asi pues, primero de todo los normalizamos el conjunto de entrenamiento y test utilizando el MinMax scaler.
scaler = MinMaxScaler()
X_train_standarized = scaler.fit_transform(X_train_copia)
X_test_standarized = scaler.transform(X_test_copia)
knn = KNeighborsClassifier()
print(np.mean(cross_val_score(knn, X_train_standarized, y_train, cv=10)))
0.9685404116712123
Vemos que obtenemos un muy buen error de validación cruzada. Además este es mucho mejor que los errores de validación de los modelos de Naïve Bayes Bernoulli y de NB Gausiano.
Para poder ajustar el modelo lo mejor posible, exploraremos para los distintos hiperpárametros los mejores valores que permiten ajustar los datos usando el modelo KNN.
Exploraremos:
Notamos que para el conjunto de hiperparámetros que siguen tendremos: 504 combinaciones(12·2·3·7)
param = {'n_neighbors':[1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 15, 17],
'weights':['distance', 'uniform'],
'metric': ['l2', 'l1', 'cosine'],
'leaf_size':[1, 5, 10, 15, 20, 25, 30]}
kne = KNeighborsClassifier()
gknn = GridSearchCV(kne, param, cv=10, n_jobs=-1, refit=True);
gknn.fit(X_train_standarized, y_train);
show_html(pd.DataFrame(gknn.cv_results_).loc[:,['params', 'mean_test_score','rank_test_score']].sort_values(by='rank_test_score').head().to_html())
| params | mean_test_score | rank_test_score | |
|---|---|---|---|
| 55 | {'leaf_size': 1, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} | 0.972309 | 1 |
| 199 | {'leaf_size': 10, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} | 0.972309 | 1 |
| 415 | {'leaf_size': 25, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} | 0.972309 | 1 |
| 127 | {'leaf_size': 5, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} | 0.972309 | 1 |
| 343 | {'leaf_size': 20, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} | 0.972309 | 1 |
Como podemos ver tenemos un conjuto de hiperparámetros que da el mismo resultado hasta el sexto decimal. Vemos que todo el conjunto de hiperparámetros obtiene el mismo resultado con la misma métrica, el mismo número de vecinos, la misma función de peso, pero distinto tamaño de hoja.
Así que, a igualdad de resultados, mejor quedarnos con el resultado que usa un tamaño de hoja más grande, para reducir el tiempo de construcción del árbol y además con un tamaño de hoja grande podemos tener un mejor tiempo de consulta.
Así que nos podemos queda con la combinación 415 de:
{'leaf_size': 25, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'}
print(classification_report(gknn.predict(X_test_standarized), y_test, target_names=clases))
precision recall f1-score support
4 0.97 0.99 0.98 246
7 0.98 0.97 0.98 252
9 0.96 0.96 0.96 257
accuracy 0.97 755
macro avg 0.97 0.97 0.97 755
weighted avg 0.97 0.97 0.97 755
Podemos ver que el acierto en el test es consistente con la validación cruzada que hemos obtenido arriba. Como podemos apreciar la mejor clase de todas es la clase del dígito 4 con la mejor relación precision-recall, seguida de la clase del 7 y finalmente la peor clase, la del dígito 9.
ConfusionMatrixDisplay.from_estimator(gknn, X_test_standarized,y_test)
<sklearn.metrics._plot.confusion_matrix.ConfusionMatrixDisplay at 0x131f9ee30>
roc_auc(gknn, X_train_standarized, y_train, X_test_standarized, y_test);
Como podemos ver obtenenemos un AUC perfecta para la clase del dígito 4, seguida de unas AUC de 0.99 para las otras clases. Por lo tanto, para la clase del 4, tenemos un 100% de predicciones correctas.
Podemos usar permutation importance para ver que píxeles parecen ser los más importantes para la clasificación.
c = choice(X_test_copia.shape[0], size=300, replace=False)
pi = permutation_importance(gknn, X_test_standarized[c], y_test[c], n_jobs=-1, random_state=42)
var_imp = pd.DataFrame({'importance': pi.importances_mean}, index=data_columns[:])
var_imp.sort_values(by='importance').plot.barh(figsize=(60,80), legend=False);
En esta ejecución los píxeles más importantes, parecen ser los que se encuentran en el rango [200-400] aunque si lo volvemos a ejecutar veremos que otros píxeles tendran más o menos importancia, aunque suele ser más o menos consistente. Puede pasar que un píxel a lo mejor sea el que tenga más peso en la decisión y después ver que ese peso, para otra ejecución, tiene un peso que su importancia este en la mitad de la tabla.
X_train_bin = Binarizer(threshold=0.5).transform(X_train_copia)
X_test_bin = Binarizer(threshold=0.5).transform(X_test_copia)
X_train_bin = pd.DataFrame(X_train_bin)
X_test_bin = pd.DataFrame(X_test_bin)
scaler = MinMaxScaler()
X_train_standarized_bin = scaler.fit_transform(X_train_bin)
X_test_standarized_bin = scaler.transform(X_test_bin)
knn_bin = KNeighborsClassifier()
print(np.mean(cross_val_score(knn_bin, X_train_standarized_bin, y_train, cv=10)))
0.9599032631516982
Vemos que obtenemos un muy buen error de validación cruzada. Además este es mucho mejor que los errores de validación de los modelos de Naïve Bayes Bernoulli y de NB Gausiano pero no tant bueno como el KNN con la matriz de datos sin binarizar. Aún así conseguimos un buen error de validación cruzada.
param = {'n_neighbors':[1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 15, 17],
'weights':['distance', 'uniform'],
'metric': ['l2', 'l1', 'cosine'],
'leaf_size':[1, 5, 10, 15, 20, 25, 30]}
kne = KNeighborsClassifier()
gknn = GridSearchCV(kne, param, cv=10, n_jobs=-1, refit=True);
gknn.fit(X_train_standarized_bin, y_train);
show_html(pd.DataFrame(gknn.cv_results_).loc[:,['params', 'mean_test_score','rank_test_score']].sort_values(by='rank_test_score').head().to_html())
| params | mean_test_score | rank_test_score | |
|---|---|---|---|
| 199 | {'leaf_size': 10, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} | 0.966325 | 1 |
| 55 | {'leaf_size': 1, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} | 0.966325 | 1 |
| 415 | {'leaf_size': 25, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} | 0.966325 | 1 |
| 127 | {'leaf_size': 5, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} | 0.966325 | 1 |
| 271 | {'leaf_size': 15, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} | 0.966325 | 1 |
Otra vez, podemos ver como tenemos un conjuto de hiperparámetros que da el mismo resultado hasta el sexto decimal.
Asimismo podemos ver tenemos un conjuto de hiperparámetros que da el mismo resultado hasta el sexto decimal. Vemos que todo el conjunto de hiperparámetros obtiene el mismo resultado con la misma métrica, el mismo número de vecinos, la misma función de peso, pero distinto tamaño de hoja.
Así que, a igualdad de resultados, mejor quedarnos con el resultado que usa un tamaño de hoja más grande, para reducir el tiempo de construcción del árbol y además con un tamaño de hoja grande podemos tener un mejor tiempo de consulta.
Así que nos podemos queda con la misma combinación 415:
{'leaf_size': 25, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'}
print(classification_report(gknn.predict(X_test_standarized_bin), y_test, target_names=clases))
precision recall f1-score support
4 0.96 0.98 0.97 245
7 0.97 0.95 0.96 254
9 0.95 0.94 0.94 256
accuracy 0.96 755
macro avg 0.96 0.96 0.96 755
weighted avg 0.96 0.96 0.96 755
Podemos ver que el acierto en el test es consistente con la validación cruzada que hemos obtenido arriba.
Como podemos apreciar la mejor clase de todas es la clase del dígito 4 como había ocurrido antes con el KNN con la matriz bin binarizar. Seguimos teniendo para la clase del 4 la mejor relación precision-recall, seguida de la clase del 7 y finalmente la del dígito 9.
Apenas hay mucha diferencia entre ambos modelos, aunque podemos notar que para el modelo KNN si no binarizamos la matriz de datos funciona un poco de mejor forma.
ConfusionMatrixDisplay.from_estimator(gknn, X_test_standarized_bin, y_test)
<sklearn.metrics._plot.confusion_matrix.ConfusionMatrixDisplay at 0x13621b340>
roc_auc(gknn, X_train_standarized_bin, y_train, X_test_standarized_bin, y_test);
Ahora ninguna AUC tiene es de 1.0, però podemos decir que ahora para todas las clases las predicciones son en un 99% correctas. Lo que casi, nos permite decir que tenemos un clasificador perfecto.
c = choice(X_test_copia.shape[0], size=300, replace=False)
pi = permutation_importance(gknn, X_test_standarized_bin[c], y_test[c], n_jobs=-1, random_state=42)
var_imp = pd.DataFrame({'importance': pi.importances_mean}, index=data_columns[:])
var_imp.sort_values(by='importance').plot.barh(figsize=(60,80), legend=False);
En esta ejecución los píxeles más importantes, parecen ser los que se encuentran en el rango [400-500] y sucede exactamente lo mismo que se ha comentado en el permutation importance realizado en celdas anteriores.
Totalmente cierto, como se ha podido ver antes, con alrededor de 100 componentes podíamos explicar el 85% de la variancia de nuestros datos usando el StandardScaler() para los modelos de: Naïve Bayes Gausiano y para Naïve Bayes Bernoulli. Cabe notar que para la matriz de datos binarizada que ha usando el modelo de NB B hacían falta un poco menos de componentes, alrededor de 90/95, para explicar el 85% de la variancia. Pero aún así, con entorno a una septima parte de las componentes ya nos era suficiente.
Podemos probar cúantas componentes necesitariamos aplicando PCA usando el conjunto de datos original y usando la matriz binarizada, pero esta vez escalando ambos conjuntos usando MinMaxScaler().
X_train_standarized = X_train_copia.copy()
scaler = MinMaxScaler()
X_train_standarized[data_columns] = scaler.fit_transform(X_train_copia[data_columns])
X_train_standarized.describe().T
X_test_standarized = X_test_copia.copy()
X_test_standarized[data_columns] = scaler.transform(X_test_copia[data_columns])
X_test_standarized.describe().T
| count | mean | std | min | 25% | 50% | 75% | max | |
|---|---|---|---|---|---|---|---|---|
| 0 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 1 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 2 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 3 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 4 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 779 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 780 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 781 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 782 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 783 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
784 rows × 8 columns
myPCA = PCA().fit(X_train_standarized[data_columns]);
#PCA.explained_variance_ratio_ para comprender qué porcentaje de varianza explican los datos
print(myPCA.explained_variance_ratio_)
print(myPCA.explained_variance_ratio_.cumsum())
[1.20383131e-01 8.56801659e-02 7.67407439e-02 6.40229908e-02 4.16757764e-02 3.79377822e-02 3.41932642e-02 3.27309530e-02 2.73394291e-02 2.47745725e-02 2.26181525e-02 2.07564019e-02 1.94411296e-02 1.66629127e-02 1.43462196e-02 1.36043031e-02 1.20402580e-02 1.16023600e-02 1.10713421e-02 9.53762233e-03 9.12810753e-03 9.01239016e-03 8.40022959e-03 8.36535886e-03 7.83768807e-03 7.11331418e-03 6.88622497e-03 6.46543726e-03 6.22964289e-03 6.07464483e-03 5.59678067e-03 5.39706460e-03 5.23110454e-03 4.91791764e-03 4.73827562e-03 4.62125854e-03 4.38231360e-03 4.24869069e-03 3.95712482e-03 3.87665575e-03 3.73882802e-03 3.63387451e-03 3.38219686e-03 3.36559090e-03 3.27953394e-03 3.15811098e-03 3.00375786e-03 2.90536973e-03 2.80883092e-03 2.70035334e-03 2.59121925e-03 2.48537582e-03 2.43805641e-03 2.40658228e-03 2.29004223e-03 2.26207479e-03 2.23294914e-03 2.19105757e-03 2.10388622e-03 2.02611019e-03 1.98158382e-03 1.94959243e-03 1.83706953e-03 1.79029368e-03 1.76901487e-03 1.74210222e-03 1.69874566e-03 1.65060979e-03 1.60405721e-03 1.54911579e-03 1.49618324e-03 1.46236641e-03 1.45953475e-03 1.41124118e-03 1.40447815e-03 1.34725974e-03 1.33419148e-03 1.29495413e-03 1.27709068e-03 1.25962973e-03 1.22236479e-03 1.20696147e-03 1.17722723e-03 1.16339610e-03 1.14150277e-03 1.10320073e-03 1.07251413e-03 1.04520335e-03 1.04087326e-03 1.02679968e-03 1.01010624e-03 9.80770572e-04 9.62998995e-04 9.32614985e-04 9.30804237e-04 9.14732226e-04 9.05511556e-04 8.92341766e-04 8.84341686e-04 8.73536188e-04 8.63054563e-04 8.50156658e-04 8.32389148e-04 8.25598666e-04 8.15247236e-04 8.08028172e-04 7.91302452e-04 7.85404750e-04 7.68613596e-04 7.62997156e-04 7.52282715e-04 7.35002446e-04 7.20568043e-04 7.06484310e-04 6.97263638e-04 6.81596550e-04 6.77906412e-04 6.60453361e-04 6.48927386e-04 6.41572278e-04 6.35598606e-04 6.28607152e-04 6.17565913e-04 6.11277213e-04 6.10560673e-04 5.94181475e-04 5.91738684e-04 5.79485275e-04 5.64615772e-04 5.61173318e-04 5.53010570e-04 5.48002413e-04 5.38876791e-04 5.33353192e-04 5.25675302e-04 5.20542772e-04 5.09767029e-04 5.07400517e-04 4.97089354e-04 4.93006585e-04 4.89830979e-04 4.85156499e-04 4.79212952e-04 4.73043440e-04 4.68030024e-04 4.59149638e-04 4.57331927e-04 4.54550600e-04 4.47811280e-04 4.45245655e-04 4.33549566e-04 4.27363247e-04 4.24458149e-04 4.21488667e-04 4.15448100e-04 4.11455850e-04 4.07727624e-04 4.04182535e-04 3.92574659e-04 3.89106175e-04 3.87673722e-04 3.85686607e-04 3.82900983e-04 3.71669607e-04 3.69098098e-04 3.64240748e-04 3.59976313e-04 3.52988169e-04 3.51439375e-04 3.50770920e-04 3.47676104e-04 3.46234990e-04 3.41475085e-04 3.32648984e-04 3.29760419e-04 3.28500726e-04 3.23960735e-04 3.23118017e-04 3.19933811e-04 3.17524313e-04 3.12045281e-04 3.10210430e-04 3.06341098e-04 3.01380374e-04 2.99430939e-04 2.95650882e-04 2.93313024e-04 2.91237244e-04 2.87681808e-04 2.86068943e-04 2.82208866e-04 2.79145832e-04 2.73678144e-04 2.70658398e-04 2.69869138e-04 2.67332912e-04 2.62049175e-04 2.58597831e-04 2.56811859e-04 2.55148242e-04 2.53343998e-04 2.51222907e-04 2.48252708e-04 2.47629902e-04 2.46672984e-04 2.41584593e-04 2.40404456e-04 2.37687674e-04 2.33443547e-04 2.31601504e-04 2.30568966e-04 2.27444887e-04 2.27143627e-04 2.23414627e-04 2.23036066e-04 2.19669640e-04 2.18027913e-04 2.16331902e-04 2.14673447e-04 2.13041436e-04 2.10798016e-04 2.08797680e-04 2.07490612e-04 2.06291342e-04 2.04426693e-04 2.00319237e-04 1.99545251e-04 1.97714826e-04 1.94982655e-04 1.93454705e-04 1.89455670e-04 1.88596622e-04 1.87162061e-04 1.86305958e-04 1.84219865e-04 1.82584957e-04 1.81010358e-04 1.79490055e-04 1.78205912e-04 1.76650458e-04 1.75871383e-04 1.74062342e-04 1.72694519e-04 1.70991313e-04 1.69959843e-04 1.67336180e-04 1.66976203e-04 1.66272770e-04 1.63887634e-04 1.63498965e-04 1.62859612e-04 1.61039180e-04 1.57357726e-04 1.56504042e-04 1.54592775e-04 1.54077879e-04 1.52685648e-04 1.51339592e-04 1.50951728e-04 1.49467223e-04 1.48684825e-04 1.46497539e-04 1.45101791e-04 1.43952678e-04 1.43322105e-04 1.42480114e-04 1.39796988e-04 1.37531511e-04 1.37405573e-04 1.36193514e-04 1.35348297e-04 1.34942594e-04 1.33386752e-04 1.32698208e-04 1.30939541e-04 1.30626558e-04 1.29794153e-04 1.28516421e-04 1.27645103e-04 1.27009714e-04 1.26169516e-04 1.24142148e-04 1.23952145e-04 1.23090174e-04 1.22125656e-04 1.21644861e-04 1.19118031e-04 1.18742114e-04 1.17710049e-04 1.16952561e-04 1.15730910e-04 1.14859115e-04 1.14205443e-04 1.13226046e-04 1.11808090e-04 1.10294181e-04 1.09549624e-04 1.08538731e-04 1.08225994e-04 1.07316513e-04 1.06798747e-04 1.04967676e-04 1.04828559e-04 1.02903894e-04 1.01653558e-04 1.01411403e-04 1.00960463e-04 9.85747690e-05 9.84245139e-05 9.78532935e-05 9.75656815e-05 9.69059492e-05 9.50200889e-05 9.45012935e-05 9.31820460e-05 9.22634842e-05 9.14667021e-05 8.99545001e-05 8.90336567e-05 8.83631530e-05 8.81336699e-05 8.75371233e-05 8.67586098e-05 8.57430420e-05 8.50970260e-05 8.35766080e-05 8.32330663e-05 8.21238235e-05 8.14231172e-05 8.13076102e-05 8.07384988e-05 8.04961536e-05 7.98642480e-05 7.88865234e-05 7.81980323e-05 7.67646478e-05 7.62838305e-05 7.60239115e-05 7.55142450e-05 7.41224076e-05 7.35136646e-05 7.28558367e-05 7.20679962e-05 7.16472308e-05 7.09332955e-05 7.07883240e-05 7.03454440e-05 6.92632893e-05 6.90546690e-05 6.77856383e-05 6.68483802e-05 6.66455463e-05 6.62889196e-05 6.47686422e-05 6.42365422e-05 6.40057772e-05 6.29855705e-05 6.23013637e-05 6.14695683e-05 6.03578550e-05 6.01159338e-05 5.95779919e-05 5.94267186e-05 5.83761020e-05 5.74355934e-05 5.58098783e-05 5.54127798e-05 5.49369041e-05 5.45716385e-05 5.40374573e-05 5.34850842e-05 5.31568603e-05 5.23570621e-05 5.11997553e-05 5.09507143e-05 5.05055450e-05 5.00185230e-05 4.95112111e-05 4.93448502e-05 4.81597583e-05 4.76888009e-05 4.67232851e-05 4.62826953e-05 4.58624926e-05 4.48913236e-05 4.46309205e-05 4.34878160e-05 4.31946963e-05 4.25389394e-05 4.19323269e-05 4.15832190e-05 4.12054430e-05 4.07166135e-05 4.02543471e-05 3.97580503e-05 3.92507438e-05 3.82590389e-05 3.81130822e-05 3.76803640e-05 3.74242211e-05 3.69747753e-05 3.66531035e-05 3.59809811e-05 3.51504376e-05 3.49405193e-05 3.47213949e-05 3.41366129e-05 3.38083053e-05 3.30654613e-05 3.26278656e-05 3.21459439e-05 3.19012640e-05 3.13191694e-05 3.07613332e-05 3.00219760e-05 2.99591612e-05 2.94063992e-05 2.92491909e-05 2.89743816e-05 2.84058955e-05 2.79720864e-05 2.74821439e-05 2.72096995e-05 2.67350203e-05 2.63331358e-05 2.59144913e-05 2.58735750e-05 2.54731199e-05 2.51773851e-05 2.50524363e-05 2.44813402e-05 2.40705039e-05 2.39874570e-05 2.34633543e-05 2.29477584e-05 2.25093611e-05 2.22155074e-05 2.20790247e-05 2.17591048e-05 2.16204297e-05 2.09121899e-05 2.05392893e-05 2.03250283e-05 2.01961925e-05 1.93426285e-05 1.91686034e-05 1.87001598e-05 1.84466937e-05 1.83406764e-05 1.78923026e-05 1.75606832e-05 1.73474446e-05 1.72135691e-05 1.70523572e-05 1.69307127e-05 1.66227203e-05 1.60851859e-05 1.58323274e-05 1.56102455e-05 1.52779066e-05 1.50378730e-05 1.46476501e-05 1.44700666e-05 1.42400809e-05 1.40848570e-05 1.38950226e-05 1.37986828e-05 1.32756252e-05 1.32587055e-05 1.30379892e-05 1.28746568e-05 1.25425461e-05 1.24703562e-05 1.22614736e-05 1.20926196e-05 1.18893911e-05 1.15410491e-05 1.14312145e-05 1.11562329e-05 1.09174748e-05 1.07658086e-05 1.06691380e-05 1.03051144e-05 1.00914783e-05 1.00308370e-05 1.00105601e-05 9.85925181e-06 9.77759963e-06 9.42679737e-06 9.33693994e-06 9.11459734e-06 8.96814466e-06 8.68713036e-06 8.63229224e-06 8.52644617e-06 8.48286354e-06 8.29080342e-06 8.19835206e-06 7.91258013e-06 7.76493607e-06 7.63260892e-06 7.43546425e-06 7.07462662e-06 6.98711605e-06 6.88829986e-06 6.72560060e-06 6.66911051e-06 6.52727390e-06 6.41030577e-06 6.23340512e-06 6.11257093e-06 5.97925248e-06 5.96601846e-06 5.89562220e-06 5.68216483e-06 5.58898373e-06 5.41786022e-06 5.38145306e-06 5.34834250e-06 5.28383801e-06 5.12427048e-06 5.02975476e-06 4.95783261e-06 4.93473855e-06 4.88150956e-06 4.77992755e-06 4.70717199e-06 4.40771325e-06 4.27440899e-06 4.16876694e-06 4.05280868e-06 4.01325067e-06 3.88186425e-06 3.81966994e-06 3.71032307e-06 3.63065185e-06 3.55203061e-06 3.47632242e-06 3.39332925e-06 3.35410784e-06 3.28931809e-06 3.23147335e-06 3.11392115e-06 3.06018982e-06 3.03378492e-06 2.96781626e-06 2.81789482e-06 2.68666764e-06 2.53853728e-06 2.39661656e-06 2.35842783e-06 2.23394153e-06 2.18138955e-06 2.10511382e-06 2.08287706e-06 1.96971540e-06 1.92647522e-06 1.89934432e-06 1.78642586e-06 1.70248716e-06 1.66650894e-06 1.63804545e-06 1.51781612e-06 1.39373417e-06 1.33832668e-06 1.24476222e-06 1.21730908e-06 1.18446640e-06 1.15560785e-06 1.01494135e-06 9.85391689e-07 9.22558126e-07 8.60985355e-07 8.09482328e-07 7.91277283e-07 7.64520475e-07 7.34348708e-07 6.09812977e-07 5.59687378e-07 5.12546038e-07 4.61087216e-07 4.23521135e-07 4.09430003e-07 4.02353357e-07 3.93384177e-07 3.72248264e-07 3.48924231e-07 3.37096656e-07 3.11758092e-07 1.56647635e-07 1.33880106e-07 9.00109234e-08 8.78809905e-08 5.23582187e-08 9.33887816e-09 4.25784769e-10 2.44230025e-32 1.23966762e-32 1.10048686e-32 9.75635234e-33 7.39449157e-33 6.41075181e-33 5.86377201e-33 4.53084933e-33 4.15305497e-33 3.66377742e-33 3.01020083e-33 2.54292667e-33 2.40526295e-33 1.90295864e-33 1.70136720e-33 1.69440330e-33 1.32362540e-33 1.18413494e-33 1.08471904e-33 8.16043969e-34 7.66312636e-34 5.80920191e-34 5.50721133e-34 5.49776984e-34 5.02864392e-34 4.91223899e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34 3.41433752e-34 3.05029223e-34 1.69181151e-34 1.66196005e-34 8.33750200e-35 6.22730721e-35 8.66877011e-36] [0.12038313 0.2060633 0.28280404 0.34682703 0.38850281 0.42644059 0.46063385 0.49336481 0.52070424 0.54547881 0.56809696 0.58885336 0.60829449 0.62495741 0.63930363 0.65290793 0.66494819 0.67655055 0.68762189 0.69715951 0.70628762 0.71530001 0.72370024 0.7320656 0.73990329 0.7470166 0.75390282 0.76036826 0.7665979 0.77267255 0.77826933 0.78366639 0.7888975 0.79381542 0.79855369 0.80317495 0.80755726 0.81180596 0.81576308 0.81963974 0.82337856 0.82701244 0.83039464 0.83376023 0.83703976 0.84019787 0.84320163 0.846107 0.84891583 0.85161618 0.8542074 0.85669278 0.85913083 0.86153742 0.86382746 0.86608953 0.86832248 0.87051354 0.87261743 0.87464354 0.87662512 0.87857471 0.88041178 0.88220208 0.88397109 0.88571319 0.88741194 0.88906255 0.89066661 0.89221572 0.89371191 0.89517427 0.89663381 0.89804505 0.89944953 0.90079679 0.90213098 0.90342593 0.90470302 0.90596265 0.90718502 0.90839198 0.90956921 0.9107326 0.9118741 0.9129773 0.91404982 0.91509502 0.9161359 0.9171627 0.9181728 0.91915357 0.92011657 0.92104919 0.92197999 0.92289472 0.92380023 0.92469258 0.92557692 0.92645045 0.92731351 0.92816366 0.92899605 0.92982165 0.9306369 0.93144493 0.93223623 0.93302164 0.93379025 0.93455325 0.93530553 0.93604053 0.9367611 0.93746758 0.93816485 0.93884644 0.93952435 0.9401848 0.94083373 0.9414753 0.9421109 0.94273951 0.94335707 0.94396835 0.94457891 0.94517309 0.94576483 0.94634432 0.94690893 0.94747011 0.94802312 0.94857112 0.94911 0.94964335 0.95016903 0.95068957 0.95119934 0.95170674 0.95220383 0.95269683 0.95318666 0.95367182 0.95415103 0.95462408 0.95509211 0.95555126 0.95600859 0.95646314 0.95691095 0.95735619 0.95778974 0.95821711 0.95864157 0.95906305 0.9594785 0.95988996 0.96029769 0.96070187 0.96109444 0.96148355 0.96187122 0.96225691 0.96263981 0.96301148 0.96338058 0.96374482 0.9641048 0.96445778 0.96480922 0.96515999 0.96550767 0.9658539 0.96619538 0.96652803 0.96685779 0.96718629 0.96751025 0.96783337 0.9681533 0.96847083 0.96878287 0.96909308 0.96939942 0.9697008 0.97000024 0.97029589 0.9705892 0.97088044 0.97116812 0.97145419 0.9717364 0.97201554 0.97228922 0.97255988 0.97282975 0.97309708 0.97335913 0.97361773 0.97387454 0.97412969 0.97438303 0.97463425 0.97488251 0.97513014 0.97537681 0.97561839 0.9758588 0.97609649 0.97632993 0.97656153 0.9767921 0.97701955 0.97724669 0.9774701 0.97769314 0.97791281 0.97813084 0.97834717 0.97856184 0.97877488 0.97898568 0.97919448 0.97940197 0.97960826 0.97981269 0.98001301 0.98021255 0.98041027 0.98060525 0.98079871 0.98098816 0.98117676 0.98136392 0.98155023 0.98173445 0.98191703 0.98209804 0.98227753 0.98245574 0.98263239 0.98280826 0.98298232 0.98315502 0.98332601 0.98349597 0.9836633 0.98383028 0.98399655 0.98416044 0.98432394 0.9844868 0.98464784 0.98480519 0.9849617 0.98511629 0.98527037 0.98542306 0.98557439 0.98572535 0.98587481 0.9860235 0.98617 0.9863151 0.98645905 0.98660237 0.98674485 0.98688465 0.98702218 0.98715959 0.98729578 0.98743113 0.98756607 0.98769946 0.98783216 0.9879631 0.98809372 0.98822352 0.98835203 0.98847968 0.98860669 0.98873286 0.988857 0.98898095 0.98910404 0.98922617 0.98934781 0.98946693 0.98958567 0.98970338 0.98982033 0.98993607 0.99005092 0.99016513 0.99027836 0.99039016 0.99050046 0.99061001 0.99071855 0.99082677 0.99093409 0.99104089 0.99114586 0.99125068 0.99135359 0.99145524 0.99155665 0.99165761 0.99175619 0.99185461 0.99195247 0.99205003 0.99214694 0.99224196 0.99233646 0.99242964 0.9925219 0.99261337 0.99270333 0.99279236 0.99288072 0.99296886 0.99305639 0.99314315 0.9932289 0.99331399 0.99339757 0.9934808 0.99356293 0.99364435 0.99372566 0.9938064 0.99388689 0.99396676 0.99404564 0.99412384 0.9942006 0.99427689 0.99435291 0.99442843 0.99450255 0.99457606 0.99464892 0.99472099 0.99479263 0.99486357 0.99493436 0.9950047 0.99507396 0.99514302 0.9952108 0.99527765 0.9953443 0.99541059 0.99547536 0.99553959 0.9956036 0.99566658 0.99572889 0.99579035 0.99585071 0.99591083 0.99597041 0.99602983 0.99608821 0.99614565 0.99620145 0.99625687 0.9963118 0.99636638 0.99642041 0.9964739 0.99652706 0.99657941 0.99663061 0.99668156 0.99673207 0.99678209 0.9968316 0.99688094 0.9969291 0.99697679 0.99702352 0.9970698 0.99711566 0.99716055 0.99720518 0.99724867 0.99729187 0.9973344 0.99737634 0.99741792 0.99745913 0.99749984 0.9975401 0.99757985 0.9976191 0.99765736 0.99769548 0.99773316 0.99777058 0.99780756 0.99784421 0.99788019 0.99791534 0.99795028 0.997985 0.99801914 0.99805295 0.99808601 0.99811864 0.99815079 0.99818269 0.99821401 0.99824477 0.99827479 0.99830475 0.99833416 0.99836341 0.99839238 0.99842079 0.99844876 0.99847624 0.99850345 0.99853018 0.99855652 0.99858243 0.99860831 0.99863378 0.99865896 0.99868401 0.99870849 0.99873256 0.99875655 0.99878001 0.99880296 0.99882547 0.99884768 0.99886976 0.99889152 0.99891314 0.99893405 0.99895459 0.99897492 0.99899512 0.99901446 0.99903363 0.99905233 0.99907077 0.99908911 0.99910701 0.99912457 0.99914191 0.99915913 0.99917618 0.99919311 0.99920973 0.99922582 0.99924165 0.99925726 0.99927254 0.99928758 0.99930223 0.9993167 0.99933094 0.99934502 0.99935892 0.99937271 0.99938599 0.99939925 0.99941229 0.99942516 0.9994377 0.99945017 0.99946244 0.99947453 0.99948642 0.99949796 0.99950939 0.99952055 0.99953146 0.99954223 0.9995529 0.9995632 0.99957329 0.99958333 0.99959334 0.9996032 0.99961297 0.9996224 0.99963174 0.99964085 0.99964982 0.99965851 0.99966714 0.99967567 0.99968415 0.99969244 0.99970064 0.99970855 0.99971631 0.99972395 0.99973138 0.99973846 0.99974544 0.99975233 0.99975906 0.99976573 0.99977225 0.99977867 0.9997849 0.99979101 0.99979699 0.99980296 0.99980885 0.99981453 0.99982012 0.99982554 0.99983092 0.99983627 0.99984155 0.99984668 0.99985171 0.99985667 0.9998616 0.99986648 0.99987126 0.99987597 0.99988038 0.99988465 0.99988882 0.99989287 0.99989689 0.99990077 0.99990459 0.9999083 0.99991193 0.99991548 0.99991896 0.99992235 0.99992571 0.99992899 0.99993223 0.99993534 0.9999384 0.99994143 0.9999444 0.99994722 0.99994991 0.99995244 0.99995484 0.9999572 0.99995943 0.99996162 0.99996372 0.9999658 0.99996777 0.9999697 0.9999716 0.99997339 0.99997509 0.99997675 0.99997839 0.99997991 0.9999813 0.99998264 0.99998389 0.9999851 0.99998629 0.99998744 0.99998846 0.99998944 0.99999037 0.99999123 0.99999204 0.99999283 0.99999359 0.99999433 0.99999494 0.9999955 0.99999601 0.99999647 0.99999689 0.9999973 0.99999771 0.9999981 0.99999847 0.99999882 0.99999916 0.99999947 0.99999963 0.99999976 0.99999985 0.99999994 0.99999999 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. ]
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.singular_values_ )+1),myPCA.singular_values_ ,alpha=0.8,marker='.');
#La nueva base son los vectores propios de la matriz de covarianza.
y_label = plt.ylabel('Vectores propios');
x_label = plt.xlabel('Componentes');
plt.title('Scree plot');
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
np.cumsum(myPCA.explained_variance_ratio_),
c='red',marker='.',
label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
plt.axhline(y=0.85, color='g', linestyle='-')
<matplotlib.lines.Line2D at 0x147085a20>
Podemos ver que usando MinMaxScaler() a la matriz original obtenemos que con alrededor de 50 podemos explicar el 85% de la variancia de los datos, cuando usando StandardScaler() solo podiamos hacerlo con un poco más de 100 componentes.
transformed_train = myPCA.transform(X_train_standarized[X_train_copia.columns])
transformed_train
X_train_standarized[['PC1','PC2','PC3']] = transformed_train[:,:3]
fig = plt.figure(figsize=(8,8))
_ = sns.scatterplot(x='PC1', y='PC2', data=X_train_standarized, hue=y_train, palette='tab10')
Podemos apreciar una mejor separabilidad de las clases, sobretodo para la clase del 7 aunque podemos seguir viendo que para la clase del 4 y del 9 el conjunto de datos parece aún agruparse.
import plotly.express as px
fig = px.scatter_3d(X_train_standarized, x='PC1', y='PC2', z='PC3',color=y_train)
fig.show()
from sklearn.manifold import TSNE
transformed_train = TSNE(n_components=2, perplexity=10, n_iter=2000, init='pca').fit_transform(X_train_standarized[data_columns])
fig = plt.figure(figsize=(8,8))
sns.scatterplot(x=transformed_train[:,0], y=transformed_train[:,1], hue=y_train, palette='tab10');
Vemos que obtenemos una mejor visión de separabilidad de las clases si lo comparamos con el primer plot de t-SNE que hemos realizado usando la matriz de datos original. Este es mejor, ya que parece que tenemos los puntos mas juntos con puntos de su misma clase y no se nos han creado tantos conjuntos pequeños de puntos de la misma clase.
Con respecto al segundo plot de t-SNE no podemos apreciar casi distinciones, además contamos con un componente random a la hora de realizar este método
Veremos que tenemos el mismo resultado que hemos obtenido cuando hemos mostrado el PCA con los datos binarizados, puesto que la transformación será la misma usando StandardScaler() que MinMax() debido a la naturaleza de los datos binarizados.
X_train_bin = Binarizer(threshold=0.5).transform(X_train_copia)
X_test_bin = Binarizer(threshold=0.5).transform(X_test_copia)
X_train_bin.shape, X_test_bin.shape
((4514, 784), (755, 784))
X_train_bin = pd.DataFrame(X_train_bin)
X_test_bin = pd.DataFrame(X_test_bin)
X_train_bin.shape, X_test_bin.shape
X_train_bin_2 = X_train_bin.copy()
X_test_bin_2 = X_test_bin.copy()
X_train_standarized_bin = X_train_bin_2.copy()
scaler = MinMaxScaler()
X_train_standarized_bin[data_columns] = scaler.fit_transform(X_train_bin_2[data_columns])
X_train_standarized_bin.describe().T
X_test_standarized_bin = X_test_bin_2.copy()
X_test_standarized_bin[data_columns] = scaler.transform(X_test_bin_2[data_columns])
X_test_standarized_bin.describe().T
| count | mean | std | min | 25% | 50% | 75% | max | |
|---|---|---|---|---|---|---|---|---|
| 0 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 1 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 2 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 3 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 4 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 779 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 780 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 781 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 782 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 783 | 755.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
784 rows × 8 columns
myPCA = PCA().fit(X_train_standarized_bin[data_columns]);
#PCA.explained_variance_ratio_ para comprender qué porcentaje de varianza explican los datos
print(myPCA.explained_variance_ratio_)
print(myPCA.explained_variance_ratio_.cumsum())
[9.86798398e-02 7.04159474e-02 6.36020040e-02 5.31339161e-02 3.52681806e-02 3.22573620e-02 2.92687983e-02 2.81081504e-02 2.39018796e-02 2.16883416e-02 2.00622161e-02 1.80625948e-02 1.71227051e-02 1.48541649e-02 1.27857931e-02 1.22601056e-02 1.08417855e-02 1.04941546e-02 1.01347878e-02 8.92418783e-03 8.42672796e-03 8.39248180e-03 7.92445291e-03 7.67216304e-03 7.26547858e-03 6.76383979e-03 6.59597574e-03 6.32187391e-03 5.93263536e-03 5.90091617e-03 5.56263645e-03 5.30204256e-03 5.12971018e-03 4.85244121e-03 4.75997704e-03 4.61781320e-03 4.41360918e-03 4.37273155e-03 4.06526852e-03 3.95588871e-03 3.81041156e-03 3.74375705e-03 3.66060359e-03 3.52344667e-03 3.49995732e-03 3.31201567e-03 3.15033722e-03 3.11434482e-03 3.02280040e-03 2.98051696e-03 2.84618846e-03 2.78909934e-03 2.74665561e-03 2.71329826e-03 2.61310964e-03 2.59562078e-03 2.55321005e-03 2.52241692e-03 2.47551531e-03 2.41137283e-03 2.37521385e-03 2.28800414e-03 2.24981956e-03 2.19382900e-03 2.16139375e-03 2.14203895e-03 2.11876075e-03 2.09488626e-03 2.04760584e-03 2.02373766e-03 1.98127750e-03 1.92705662e-03 1.90018920e-03 1.86134698e-03 1.85379294e-03 1.83663645e-03 1.82205620e-03 1.78287565e-03 1.77113778e-03 1.74660904e-03 1.72013074e-03 1.70774423e-03 1.67188255e-03 1.64253119e-03 1.62566053e-03 1.60717981e-03 1.58540266e-03 1.57384066e-03 1.56113555e-03 1.54271278e-03 1.52758166e-03 1.50891465e-03 1.47906087e-03 1.45207754e-03 1.42431058e-03 1.41221494e-03 1.40669552e-03 1.38816917e-03 1.36743791e-03 1.35985192e-03 1.34537646e-03 1.33413717e-03 1.31796140e-03 1.31145211e-03 1.30437260e-03 1.29486502e-03 1.28165518e-03 1.27678099e-03 1.25415287e-03 1.23507083e-03 1.22088650e-03 1.20770298e-03 1.20491738e-03 1.20306865e-03 1.18048109e-03 1.17629956e-03 1.16734655e-03 1.15378401e-03 1.15194593e-03 1.13981288e-03 1.13078954e-03 1.11674440e-03 1.11069671e-03 1.10134205e-03 1.08972615e-03 1.07777265e-03 1.07066318e-03 1.06349559e-03 1.05719198e-03 1.04944405e-03 1.04042456e-03 1.03573069e-03 1.03074442e-03 1.02091352e-03 1.01608538e-03 1.00900307e-03 9.98746368e-04 9.88304753e-04 9.84607681e-04 9.71511141e-04 9.62230990e-04 9.58754218e-04 9.55635643e-04 9.47094852e-04 9.41108245e-04 9.35137075e-04 9.25800262e-04 9.21307613e-04 9.09499199e-04 8.97888146e-04 8.94400181e-04 8.87746524e-04 8.83773471e-04 8.76684104e-04 8.68235669e-04 8.62673790e-04 8.55291458e-04 8.50009733e-04 8.45057473e-04 8.41253158e-04 8.31717885e-04 8.27100045e-04 8.25614454e-04 8.15480878e-04 8.14286513e-04 8.05906104e-04 8.00796688e-04 7.96109391e-04 7.94519796e-04 7.85594602e-04 7.82977209e-04 7.79700148e-04 7.76711828e-04 7.65885923e-04 7.63033953e-04 7.58816942e-04 7.54659364e-04 7.44889572e-04 7.37053808e-04 7.33610340e-04 7.30261998e-04 7.25011430e-04 7.20200103e-04 7.15815206e-04 7.08858203e-04 7.05746267e-04 7.03524279e-04 7.00395356e-04 6.95550428e-04 6.91398213e-04 6.87295558e-04 6.83692415e-04 6.76950689e-04 6.69072701e-04 6.65939212e-04 6.62761454e-04 6.60020653e-04 6.59435212e-04 6.46938361e-04 6.45511470e-04 6.43407399e-04 6.36852592e-04 6.32326600e-04 6.29064424e-04 6.24932086e-04 6.21071727e-04 6.14941311e-04 6.12668854e-04 6.10835455e-04 6.03096616e-04 5.99910316e-04 5.96380621e-04 5.93975497e-04 5.90131016e-04 5.85771507e-04 5.80926022e-04 5.75120492e-04 5.71561237e-04 5.67441902e-04 5.61100253e-04 5.57855464e-04 5.53285354e-04 5.49820453e-04 5.47781751e-04 5.42649063e-04 5.38337605e-04 5.35100002e-04 5.31700401e-04 5.22781947e-04 5.21881014e-04 5.14738914e-04 5.14217712e-04 5.09661825e-04 5.03586191e-04 4.99509339e-04 4.94909433e-04 4.90163577e-04 4.88464119e-04 4.84587062e-04 4.82223654e-04 4.80513044e-04 4.76291574e-04 4.69242905e-04 4.65049603e-04 4.62839502e-04 4.60928268e-04 4.58550521e-04 4.52943767e-04 4.49041719e-04 4.45190543e-04 4.41593561e-04 4.41096751e-04 4.38877024e-04 4.34621049e-04 4.31043083e-04 4.26431344e-04 4.22481408e-04 4.20759511e-04 4.19086833e-04 4.14392809e-04 4.12367475e-04 4.11452647e-04 4.02959512e-04 4.01350053e-04 3.99864877e-04 3.97326418e-04 3.93804489e-04 3.89925146e-04 3.86694479e-04 3.82654222e-04 3.80257242e-04 3.76516964e-04 3.72924242e-04 3.70684400e-04 3.68154395e-04 3.63851409e-04 3.61565063e-04 3.59963610e-04 3.55215555e-04 3.51211804e-04 3.46752540e-04 3.43744340e-04 3.40998336e-04 3.39686347e-04 3.31673591e-04 3.29525289e-04 3.25993664e-04 3.24733500e-04 3.22226523e-04 3.20443816e-04 3.16299551e-04 3.14485477e-04 3.08342379e-04 3.04034344e-04 2.99029148e-04 2.97796746e-04 2.96375830e-04 2.92736001e-04 2.91812454e-04 2.86393214e-04 2.84505154e-04 2.80889512e-04 2.78772619e-04 2.76958587e-04 2.74852838e-04 2.72564847e-04 2.68150468e-04 2.63407197e-04 2.60589752e-04 2.57453959e-04 2.56233766e-04 2.53213954e-04 2.50362918e-04 2.46603739e-04 2.43228465e-04 2.41414425e-04 2.39541979e-04 2.36901331e-04 2.32609357e-04 2.31961344e-04 2.28438285e-04 2.24517386e-04 2.22968118e-04 2.18678509e-04 2.14969009e-04 2.14144381e-04 2.11991428e-04 2.09808964e-04 2.06169803e-04 2.03263299e-04 2.00161172e-04 1.97690155e-04 1.96313561e-04 1.92906123e-04 1.91316689e-04 1.89201981e-04 1.86818593e-04 1.83459887e-04 1.82419298e-04 1.80549411e-04 1.77993216e-04 1.75093863e-04 1.70763435e-04 1.69372391e-04 1.66622832e-04 1.61761122e-04 1.61115293e-04 1.59300549e-04 1.57434929e-04 1.55936605e-04 1.55273682e-04 1.54205401e-04 1.52421389e-04 1.50806017e-04 1.48238961e-04 1.46391244e-04 1.44028162e-04 1.42212403e-04 1.41223272e-04 1.37246426e-04 1.36308794e-04 1.34671823e-04 1.33080656e-04 1.32465076e-04 1.30329486e-04 1.26506833e-04 1.24942744e-04 1.23617101e-04 1.22373191e-04 1.21344186e-04 1.18966008e-04 1.17825607e-04 1.16129981e-04 1.13816623e-04 1.12067828e-04 1.11389139e-04 1.10624665e-04 1.09465208e-04 1.08523646e-04 1.05962625e-04 1.04902058e-04 1.03308464e-04 1.00360259e-04 9.96922125e-05 9.81542680e-05 9.65107590e-05 9.63001216e-05 9.51725187e-05 9.36350641e-05 9.02760938e-05 9.01417386e-05 8.96320984e-05 8.71310962e-05 8.67546496e-05 8.51812901e-05 8.26372461e-05 8.15129991e-05 8.06371423e-05 7.85563545e-05 7.72131947e-05 7.70403713e-05 7.63940619e-05 7.46662773e-05 7.20446998e-05 7.02455412e-05 6.93631234e-05 6.86414049e-05 6.73050980e-05 6.63883691e-05 6.51019853e-05 6.42237218e-05 6.35940616e-05 6.27659536e-05 6.22173437e-05 6.14951949e-05 5.97647363e-05 5.91207376e-05 5.84643300e-05 5.74801057e-05 5.67875485e-05 5.63392551e-05 5.50444872e-05 5.41714096e-05 5.26620173e-05 5.19051757e-05 5.17649695e-05 5.02842806e-05 4.98319165e-05 4.95129501e-05 4.89616906e-05 4.72960705e-05 4.66765970e-05 4.58199825e-05 4.46250585e-05 4.44306841e-05 4.28951952e-05 4.21669020e-05 4.20280791e-05 3.97174154e-05 3.96513451e-05 3.83120521e-05 3.80815504e-05 3.71227003e-05 3.67371472e-05 3.65751940e-05 3.55179813e-05 3.51512148e-05 3.47859768e-05 3.42312849e-05 3.35412594e-05 3.32326056e-05 3.22203835e-05 3.21044284e-05 3.15462175e-05 3.10160189e-05 3.04694549e-05 2.97913575e-05 2.94674543e-05 2.91453011e-05 2.78808043e-05 2.77236068e-05 2.72665793e-05 2.68379427e-05 2.62597852e-05 2.55039548e-05 2.51671971e-05 2.47633887e-05 2.40094533e-05 2.34012481e-05 2.27479373e-05 2.26812987e-05 2.20862148e-05 2.11492952e-05 2.05902495e-05 2.01656202e-05 2.01195572e-05 1.94797566e-05 1.93270485e-05 1.87820724e-05 1.86516371e-05 1.84468542e-05 1.79176149e-05 1.76865882e-05 1.66458325e-05 1.61443651e-05 1.59074920e-05 1.52864376e-05 1.51998708e-05 1.51827973e-05 1.48990285e-05 1.46495099e-05 1.41370327e-05 1.39017144e-05 1.38153532e-05 1.30943254e-05 1.27843340e-05 1.22953110e-05 1.18195252e-05 1.15811754e-05 1.13010252e-05 1.09883982e-05 1.04959232e-05 1.04750745e-05 1.01876689e-05 9.94403235e-06 9.70976490e-06 9.43689191e-06 9.33290900e-06 9.10932240e-06 8.78696455e-06 8.69260515e-06 8.33673784e-06 8.21084539e-06 8.13849900e-06 7.95688455e-06 7.65345549e-06 7.18026630e-06 6.91811800e-06 6.75946574e-06 6.67847134e-06 6.60827899e-06 6.31919071e-06 5.95416943e-06 5.74707056e-06 5.56694711e-06 5.39032235e-06 5.21366606e-06 5.19893354e-06 4.95223472e-06 4.76708093e-06 4.50989051e-06 4.46797500e-06 4.26204159e-06 4.18115481e-06 4.15701256e-06 3.98835822e-06 3.77539879e-06 3.56581890e-06 3.53663832e-06 3.21958550e-06 3.10378880e-06 3.05684819e-06 3.02621799e-06 2.73889694e-06 2.69730203e-06 2.66023779e-06 2.51080690e-06 2.45319987e-06 2.38420955e-06 2.25307503e-06 2.03850701e-06 1.96147857e-06 1.84674802e-06 1.60566854e-06 1.42747044e-06 1.35808602e-06 1.23842396e-06 1.21138234e-06 1.15899041e-06 1.12118114e-06 9.64891887e-07 8.53512378e-07 8.32853898e-07 7.75026313e-07 7.63510748e-07 6.22234458e-07 4.24219140e-07 3.45987888e-07 3.28079315e-07 1.96049565e-32 6.47531246e-33 5.16192985e-33 4.68768237e-33 4.06556242e-33 4.01784362e-33 3.66222022e-33 3.09073295e-33 2.61804802e-33 2.47990181e-33 2.37282080e-33 2.10301805e-33 1.94897094e-33 1.79492023e-33 1.77076194e-33 1.51853461e-33 1.45629031e-33 1.23013282e-33 1.20454342e-33 9.80313193e-34 7.00500055e-34 6.84576105e-34 6.56904073e-34 4.44176191e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34 3.35166108e-34 3.11518758e-34 2.98493256e-34 2.73285252e-34 1.50036002e-34 8.98153107e-35 5.87713160e-35 2.79741894e-35 4.23372289e-36] [0.09867984 0.16909579 0.23269779 0.28583171 0.32109989 0.35335725 0.38262605 0.4107342 0.43463608 0.45632442 0.47638664 0.49444923 0.51157194 0.5264261 0.53921189 0.551472 0.56231378 0.57280794 0.58294273 0.59186692 0.60029364 0.60868612 0.61661058 0.62428274 0.63154822 0.63831206 0.64490803 0.65122991 0.65716254 0.66306346 0.6686261 0.67392814 0.67905785 0.68391029 0.68867027 0.69328808 0.69770169 0.70207442 0.70613969 0.71009558 0.71390599 0.71764975 0.72131035 0.7248338 0.72833376 0.73164577 0.73479611 0.73791045 0.74093325 0.74391377 0.74675996 0.74954906 0.75229571 0.75500901 0.75762212 0.76021774 0.76277095 0.76529337 0.76776888 0.77018026 0.77255547 0.77484348 0.77709329 0.77928712 0.78144852 0.78359056 0.78570932 0.7878042 0.78985181 0.79187555 0.79385682 0.79578388 0.79768407 0.79954542 0.80139921 0.80323585 0.8050579 0.80684078 0.80861192 0.81035853 0.81207866 0.8137864 0.81545828 0.81710081 0.81872647 0.82033365 0.82191906 0.8234929 0.82505403 0.82659675 0.82812433 0.82963324 0.8311123 0.83256438 0.83398869 0.83540091 0.8368076 0.83819577 0.83956321 0.84092306 0.84226844 0.84360257 0.84492054 0.84623199 0.84753636 0.84883123 0.85011288 0.85138966 0.85264381 0.85387889 0.85509977 0.85630748 0.85751239 0.85871546 0.85989594 0.86107224 0.86223959 0.86339337 0.86454532 0.86568513 0.86681592 0.86793267 0.86904336 0.8701447 0.87123443 0.8723122 0.87338287 0.87444636 0.87550355 0.876553 0.87759342 0.87862915 0.8796599 0.88068081 0.8816969 0.8827059 0.88370465 0.88469295 0.88567756 0.88664907 0.8876113 0.88857005 0.88952569 0.89047278 0.89141389 0.89234903 0.89327483 0.89419614 0.89510564 0.89600353 0.89689793 0.89778567 0.89866945 0.89954613 0.90041437 0.90127704 0.90213233 0.90298234 0.9038274 0.90466865 0.90550037 0.90632747 0.90715308 0.90796856 0.90878285 0.90958876 0.91038955 0.91118566 0.91198018 0.91276578 0.91354875 0.91432845 0.91510517 0.91587105 0.91663409 0.9173929 0.91814756 0.91889245 0.91962951 0.92036312 0.92109338 0.92181839 0.92253859 0.92325441 0.92396326 0.92466901 0.92537253 0.92607293 0.92676848 0.92745988 0.92814717 0.92883087 0.92950782 0.93017689 0.93084283 0.93150559 0.93216561 0.93282505 0.93347198 0.9341175 0.9347609 0.93539776 0.93603008 0.93665915 0.93728408 0.93790515 0.93852009 0.93913276 0.9397436 0.94034669 0.9409466 0.94154298 0.94213696 0.94272709 0.94331286 0.94389379 0.94446891 0.94504047 0.94560791 0.94616901 0.94672687 0.94728015 0.94782997 0.94837775 0.9489204 0.94945874 0.94999384 0.95052554 0.95104832 0.9515702 0.95208494 0.95259916 0.95310882 0.95361241 0.95411192 0.95460683 0.95509699 0.95558546 0.95607004 0.95655227 0.95703278 0.95750907 0.95797831 0.95844336 0.9589062 0.95936713 0.95982568 0.96027863 0.96072767 0.96117286 0.96161445 0.96205555 0.96249443 0.96292905 0.96336009 0.96378652 0.964209 0.96462976 0.96504885 0.96546324 0.96587561 0.96628706 0.96669002 0.96709137 0.96749124 0.96788856 0.96828237 0.96867229 0.96905899 0.96944164 0.9698219 0.97019841 0.97057134 0.97094202 0.97131018 0.97167403 0.97203559 0.97239556 0.97275077 0.97310199 0.97344874 0.97379248 0.97413348 0.97447317 0.97480484 0.97513437 0.97546036 0.97578509 0.97610732 0.97642776 0.97674406 0.97705855 0.97736689 0.97767092 0.97796995 0.97826775 0.97856413 0.97885686 0.97914868 0.97943507 0.97971957 0.98000046 0.98027924 0.98055619 0.98083105 0.98110361 0.98137176 0.98163517 0.98189576 0.98215321 0.98240945 0.98266266 0.98291302 0.98315963 0.98340286 0.98364427 0.98388381 0.98412071 0.98435332 0.98458528 0.98481372 0.98503824 0.98526121 0.98547989 0.98569486 0.985909 0.98612099 0.9863308 0.98653697 0.98674023 0.98694039 0.98713808 0.9873344 0.9875273 0.98771862 0.98790782 0.98809464 0.9882781 0.98846052 0.98864107 0.98881906 0.98899416 0.98916492 0.98933429 0.98950092 0.98966268 0.98982379 0.98998309 0.99014053 0.99029646 0.99045174 0.99060594 0.99075837 0.99090917 0.99105741 0.9912038 0.99134783 0.99149004 0.99163127 0.99176851 0.99190482 0.99203949 0.99217257 0.99230504 0.99243537 0.99256187 0.99268682 0.99281043 0.99293281 0.99305415 0.99317312 0.99329094 0.99340707 0.99352089 0.99363296 0.99374435 0.99385497 0.99396444 0.99407296 0.99417892 0.99428382 0.99438713 0.99448749 0.99458719 0.99468534 0.99478185 0.99487815 0.99497332 0.99506696 0.99515723 0.99524738 0.99533701 0.99542414 0.99551089 0.99559608 0.99567871 0.99576023 0.99584086 0.99591942 0.99599663 0.99607367 0.99615007 0.99622473 0.99629678 0.99636702 0.99643639 0.99650503 0.99657233 0.99663872 0.99670382 0.99676805 0.99683164 0.99689441 0.99695662 0.99701812 0.99707788 0.99713701 0.99719547 0.99725295 0.99730974 0.99736608 0.99742112 0.99747529 0.99752795 0.99757986 0.99763162 0.99768191 0.99773174 0.99778125 0.99783022 0.99787751 0.99792419 0.99797001 0.99801463 0.99805906 0.99810196 0.99814413 0.99818615 0.99822587 0.99826552 0.99830383 0.99834192 0.99837904 0.99841578 0.99845235 0.99848787 0.99852302 0.99855781 0.99859204 0.99862558 0.99865881 0.99869103 0.99872314 0.99875468 0.9987857 0.99881617 0.99884596 0.99887543 0.99890457 0.99893245 0.99896018 0.99898744 0.99901428 0.99904054 0.99906604 0.99909121 0.99911598 0.99913998 0.99916339 0.99918613 0.99920882 0.9992309 0.99925205 0.99927264 0.99929281 0.99931293 0.99933241 0.99935173 0.99937052 0.99938917 0.99940761 0.99942553 0.99944322 0.99945986 0.99947601 0.99949192 0.9995072 0.9995224 0.99953758 0.99955248 0.99956713 0.99958127 0.99959517 0.99960899 0.99962208 0.99963487 0.99964716 0.99965898 0.99967056 0.99968186 0.99969285 0.99970335 0.99971382 0.99972401 0.99973395 0.99974366 0.9997531 0.99976243 0.99977154 0.99978033 0.99978902 0.99979736 0.99980557 0.99981371 0.99982167 0.99982932 0.9998365 0.99984342 0.99985018 0.99985686 0.99986346 0.99986978 0.99987574 0.99988148 0.99988705 0.99989244 0.99989766 0.99990285 0.99990781 0.99991257 0.99991708 0.99992155 0.99992581 0.99992999 0.99993415 0.99993814 0.99994192 0.99994548 0.99994902 0.99995224 0.99995534 0.9999584 0.99996142 0.99996416 0.99996686 0.99996952 0.99997203 0.99997448 0.99997687 0.99997912 0.99998116 0.99998312 0.99998497 0.99998657 0.999988 0.99998936 0.9999906 0.99999181 0.99999297 0.99999409 0.99999505 0.99999591 0.99999674 0.99999752 0.99999828 0.9999989 0.99999933 0.99999967 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. ]
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.singular_values_ )+1),myPCA.singular_values_ ,alpha=0.8,marker='.');
#La nueva base son los vectores propios de la matriz de covarianza.
y_label = plt.ylabel('Vectores propios');
x_label = plt.xlabel('Componentes');
plt.title('Scree plot');
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
np.cumsum(myPCA.explained_variance_ratio_),
c='red',marker='.',
label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
plt.axhline(y=0.85, color='g', linestyle='-')
<matplotlib.lines.Line2D at 0x14695f310>
transformed_train = myPCA.transform(X_train_standarized_bin[X_train_bin_2.columns])
transformed_train
X_train_standarized_bin[['PC1','PC2','PC3']] = transformed_train[:,:3]
fig = plt.figure(figsize=(8,8))
_ = sns.scatterplot(x='PC1', y='PC2', data=X_train_standarized_bin, hue=y_train, palette='tab10')
Probaremos como se comportan los modelos para un cierto número de componentes, así que podemos intentar ver como se comporta el cross-validation score para los distintos números de componentes y eligiremos los primeros k componentes principales. Usaremos los componentes de PCA para reducir la dimensionalidad y comprobar si podemos reducir el tamaño sin comprometer en exceso la calidad del resultado.
Empezaremos por el modelo de Naïve Bayes Gausiano:
X_train_standarized = X_train_copia.copy()
X_test_standarized = X_test_copia.copy()
scaler = StandardScaler()
X_train_standarized[data_columns] = scaler.fit_transform(X_train_copia[data_columns])
X_test_standarized[data_columns] = scaler.transform(X_test_copia[data_columns])
myPCA = PCA().fit(X_train_standarized[data_columns]);
transformed_train = myPCA.transform(X_train_standarized[X_train_copia.columns])
transformed_test = myPCA.transform(X_test_standarized[X_train_copia.columns])
nc = 30
X_train_pca_todas = scaler.fit_transform(transformed_train[:,:])
X_train_pca_s = scaler.fit_transform(transformed_train[:,:nc])
X_test_pca_s = scaler.transform(transformed_test[:,:nc])
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
np.cumsum(myPCA.explained_variance_ratio_),
c='red',marker='.',
label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
plt.axhline(y=0.85, color='g', linestyle='-')
<matplotlib.lines.Line2D at 0x147273370>
gnb = GaussianNB()
print(np.mean(cross_val_score(gnb,X_train_pca_todas,y_train,cv=10)))
print(np.mean(cross_val_score(gnb,X_train_pca_s,y_train,cv=10)))
0.49446412102898174 0.6825373310048467
# NB Gaussià k components matriu sense binaritzar
_list = []
for i in range(1, X_train_pca_s.shape[1]+1):
score = cross_val_score(gnb, X_train_pca_s[:,:i], y_train, cv=10).mean()
print(i, score)
_list.append(score)
plt.plot(_list, '-o')
plt.xlabel('Número de componentes principales')
plt.ylabel('cross-validation score')
plt.title('Clasificación')
plt.xticks(np.arange(X_train_pca_s.shape[1]), np.arange(1, X_train_pca_s.shape[1]+1))
plt.axhline(y = np.mean(cross_val_score(gnb,X_train_pca_s,y_train,cv=10)), color='g', linestyle='-');
1 0.4395272060122049 2 0.4769592645644879 3 0.7536604987932422 4 0.749227380648706 5 0.7472337774463826 6 0.7529958008751446 7 0.7649534956733317 8 0.7992901713007475 9 0.7990684418107253 10 0.8037218177893765 11 0.8003993093028277 12 0.8309749229833407 13 0.8407226811608421 14 0.8296425838353315 15 0.837171575456704 16 0.8236583403645781 17 0.8139140160508603 18 0.7919794753056139 19 0.7740316504130448 20 0.7605193964248572 21 0.7556442909561839 22 0.7523203108137276 23 0.7341546808468891 24 0.7297235249102288 25 0.7244103565331712 26 0.7162107803700724 27 0.7095662539489435 28 0.7004861370013539 29 0.6891828385299139 30 0.6825373310048467
Podemos ver que a partir de las 13/15 componentes principales, nuestro cross-validation score decrece significativamente a medida que incrementamos las componentes, esto es así ya que nuestros datos estan ciertamente correlacionados y no son independientes como asume Naïve Bayes. Si vamos añadinendo componentes solo empeorará nuestro score.
gnb_model = GaussianNB().fit(X_train_pca_s, y_train)
print(classification_report(gnb_model.predict(X_test_pca_s), y_test))
precision recall f1-score support
4 0.44 0.81 0.57 135
7 0.68 0.97 0.80 174
9 0.93 0.53 0.67 446
accuracy 0.68 755
macro avg 0.68 0.77 0.68 755
weighted avg 0.78 0.68 0.68 755
Excepto para la clase del 4, vemos que las relaciones precision-recall han mejorado, de forma muy notable para la clase del 7. Tenemos que el recall de la clase 4 ha disminuido y juntamente con el precision de la clase del 9. Seguimos teniendo clases desbalanceadas, pero se ha reducido.
Además, vemos que nuestro modelo usando 30 componentes tiene una mayor accuracy que cuando considerábamos todas la componentes principales. Esto es así ya que al no añadir todas las componentes tendremos componentes que no están muy correlacionadas entre sí y, por lo tanto, tendremos mejores resultados. Empeorará si usamos píxeles con una variación pequeña y se descartaran al hacer el PCA antes que aplicando Naïve Bayes.
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(gnb_model, X_test_pca_s, y_test, display_labels=clases, ax=plt.subplot());
plt.figure(figsize=(8,8));
roc_auc(gnb_model, X_train_pca_s, y_train, X_test_pca_s, y_test);
Vemos que tenemos una mejor media i que la AUC de la clase del 9 es significativamente mucho mejor, ja que hemos pasado de una AUC=0.68 a una AUC=0.89. Además tenemos una mejor media, pasando de ser un 0.85 a un 0.92.
X_train_bin = Binarizer(threshold=0.5).transform(X_train_copia)
X_test_bin = Binarizer(threshold=0.5).transform(X_test_copia)
X_train_bin.shape, X_test_bin.shape
((4514, 784), (755, 784))
X_train_bin = pd.DataFrame(X_train_bin)
X_test_bin = pd.DataFrame(X_test_bin)
X_train_bin.shape, X_test_bin.shape
X_train_bin_2 = X_train_bin.copy()
X_test_bin_2 = X_test_bin.copy()
X_train_standarized_bin = X_train_bin_2.copy()
X_test_standarized_bin = X_test_bin_2.copy()
myPCA = PCA().fit(X_train_standarized_bin[data_columns]);
transformed_train_bin = myPCA.transform(X_train_standarized_bin[X_train_bin_2.columns])
transformed_test_bin = myPCA.transform(X_test_standarized_bin[X_test_bin_2.columns])
nc = 100
X_train_pca_todas_bin = scaler.fit_transform(transformed_train_bin[:,:])
X_train_pca_s_bin = scaler.fit_transform(transformed_train_bin[:,:nc])
X_test_pca_s_bin = scaler.transform(transformed_test_bin[:,:nc])
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
np.cumsum(myPCA.explained_variance_ratio_),
c='red',marker='.',
label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
plt.axhline(y=0.85, color='g', linestyle='-')
<matplotlib.lines.Line2D at 0x145786140>
bnb = BernoulliNB()
print(np.mean(cross_val_score(bnb, X_train_pca_todas_bin, y_train, cv=10)))
print(np.mean(cross_val_score(bnb, X_train_pca_s_bin, y_train, cv=10)))
0.8055020308851519 0.7753625179051469
# NB Bernoulli k components matriu sense binaritzar
_list = []
for i in range(1, X_train_pca_s_bin.shape[1]+1):
score = cross_val_score(bnb, X_train_pca_s_bin[:,:i], y_train, cv=10).mean()
print(i, score)
_list.append(score)
plt.plot(_list, '-o')
plt.xlabel('Número de componentes principales')
plt.ylabel('cross-validation score')
plt.title('Clasificación')
plt.xticks(np.arange(X_train_pca_s_bin.shape[1]), np.arange(1, X_train_pca_s_bin.shape[1]+1))
plt.axhline(y = np.mean(cross_val_score(bnb,X_train_pca_s_bin,y_train,cv=10)), color='g', linestyle='-');
1 0.45192247316680734 2 0.4951288189470793 3 0.6612684692816357 4 0.6612684692816357 5 0.6672522222004199 6 0.6650388517159507 7 0.6712404097090046 8 0.680988167886506 9 0.708227537625336 10 0.7532042854620018 11 0.7518778329376213 12 0.7521015246355198 13 0.7543193100877107 14 0.7534328826795911 15 0.7649480996016718 16 0.7649476090497027 17 0.7631786786492161 18 0.7640636344014284 19 0.7647312756313404 20 0.7682730608480662 21 0.7660587092596589 22 0.7700459156643055 23 0.7713758020524695 24 0.7700459156643055 25 0.7727047073366953 26 0.7724844495025802 27 0.7735891725369386 28 0.7749180778211644 29 0.7769121715754567 30 0.7746973294350803 31 0.7764721464591959 32 0.776473127563134 33 0.7722627200125581 34 0.7753610462492396 35 0.7749215116849478 36 0.7751427506230011 37 0.7760291780311206 38 0.7727066695445715 39 0.7735930969526912 40 0.7716014559582443 41 0.7720439338343504 42 0.7698300727979122 43 0.7696063811000137 44 0.7700493495280891 45 0.7693871043698369 46 0.7720458960422267 47 0.7753679139768067 48 0.7738162980986205 49 0.7751442222789083 50 0.7758084296450366 51 0.7735926064007221 52 0.7773566116594391 53 0.7744780527049036 54 0.7749215116849479 55 0.7733689147028235 56 0.7753639895610541 57 0.7762504169691737 58 0.7773615171791299 59 0.776251888625081 60 0.7780222906814748 61 0.7771368443772932 62 0.7758069579891294 63 0.7764706748032886 64 0.776472637011165 65 0.776472637011165 66 0.7789111708494397 67 0.7778025233993289 68 0.779795145497714 69 0.7804603339677806 70 0.7789092086415635 71 0.7782464729313423 72 0.7789106802974707 73 0.7802381139257893 74 0.7802381139257892 75 0.7815630947942624 76 0.7815630947942626 77 0.7797917116339306 78 0.7784608441418285 79 0.7797922021858995 80 0.7813428369601476 81 0.7800129505719837 82 0.7793487432058553 83 0.7804559190000588 84 0.7833354590585326 85 0.7822268116084218 86 0.7802346800620058 87 0.7813418558562094 88 0.7804559190000588 89 0.7824500127543511 90 0.7784608441418285 91 0.7806756862822046 92 0.7791255420599258 93 0.7782391146518063 94 0.7789038125699037 95 0.7789038125699037 96 0.7780193473696604 97 0.7751383356552795 98 0.7746938955712969 99 0.7766919137413417 100 0.7753625179051469
Podemos ver que a partir de las 20/22 componentes nuestro score se mantiene, y va oscilando levemente, en este caso, podemos notar que para conseguir un mayor score, vamos a necesitar de todas las componentes, sino tendremos un acuracy claramente inferior al que teníamos sin la reducción de las componentes.
bnb_model = BernoulliNB().fit(X_train_pca_s_bin, y_train)
print(classification_report(bnb_model.predict(X_test_pca_s_bin), y_test, target_names=clases))
precision recall f1-score support
4 0.70 0.85 0.77 206
7 0.82 0.82 0.82 252
9 0.84 0.72 0.78 297
accuracy 0.79 755
macro avg 0.79 0.80 0.79 755
weighted avg 0.80 0.79 0.79 755
Notamos que todas la relaciones precision-recall se han visto afectadas. Ahora si que necesitamos de muchas mas componentes, nos faltaran componentes que no esten correlacionadas para augmentar el acierto del modelo.
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(bnb_model, X_test_pca_s_bin, y_test, display_labels=clases, ax=plt.subplot());
plt.figure(figsize=(8,8));
roc_auc(bnb_model, X_train_pca_s_bin, y_train, X_test_pca_s_bin, y_test);
Como es de esperar, todas la AUC han disminuido.
X_train_standarized = X_train_copia.copy()
X_test_standarized = X_test_copia.copy()
scaler = MinMaxScaler()
X_train_standarized[data_columns] = scaler.fit_transform(X_train_copia[data_columns])
X_test_standarized[data_columns] = scaler.transform(X_test_copia[data_columns])
myPCA = PCA().fit(X_train_standarized[data_columns]);
transformed_train = myPCA.transform(X_train_standarized[X_train_copia.columns])
transformed_test = myPCA.transform(X_test_standarized[X_train_copia.columns])
nc = 30
X_train_pca_todas = scaler.fit_transform(transformed_train[:,:])
X_train_pca_s = scaler.fit_transform(transformed_train[:,:nc])
X_test_pca_s = scaler.transform(transformed_test[:,:nc])
knn = KNeighborsClassifier()
print(np.mean(cross_val_score(knn, X_train_pca_todas, y_train, cv=10)))
print(np.mean(cross_val_score(knn, X_train_pca_s, y_train, cv=10)))
0.8101465769283598 0.9667695190628495
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
np.cumsum(myPCA.explained_variance_ratio_),
c='red',marker='.',
label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
plt.axhline(y=0.85, color='g', linestyle='-')
<matplotlib.lines.Line2D at 0x13758dff0>
# KNN k components matriu sense binaritzar
_list = []
for i in range(1, X_train_pca_s.shape[1]+1):
score = cross_val_score(knn, X_train_pca_s[:,:i], y_train, cv=10).mean()
print(i, score)
_list.append(score)
plt.plot(_list, '-o')
plt.xlabel('Número de componentes principales')
plt.ylabel('cross-validation score')
plt.title('Clasificación')
plt.xticks(np.arange(X_train_pca_s.shape[1]), np.arange(1, X_train_pca_s.shape[1]+1))
plt.axhline(y = np.mean(cross_val_score(knn,X_train_pca_s,y_train,cv=10)), color='g', linestyle='-');
1 0.42289307929282033 2 0.564242685870141 3 0.7556506681317818 4 0.7957449522202382 5 0.8460314345701784 6 0.8568824441261308 7 0.875933520397151 8 0.894538194376312 9 0.9069481780899868 10 0.9293256872633087 11 0.9339731766183309 12 0.9421747149893059 13 0.9457199340698154 14 0.9514790141867631 15 0.9536963090869847 16 0.9559126228832682 17 0.9554696544551928 18 0.9579072071895297 19 0.9601191060180915 20 0.9583501756176049 21 0.9612287345721405 22 0.9601245020897513 23 0.9621166336361675 24 0.9607857661440654 25 0.9618924513863 26 0.9630010988364107 27 0.9625586209603044 28 0.9647739536526501 29 0.9665463179169201 30 0.9667695190628495
Podemos ver que con aproximadamente 30 componentes tenemos un muy buen acierto
param = {'n_neighbors':[1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 15],
'weights':['distance', 'uniform'],
'leaf_size':[1, 5, 10, 20, 25, 30],
'metric': ['l2', 'l1', 'cosine']}
knn_gs = GridSearchCV(knn,param,cv=10, n_jobs=-1)
knn_gs.fit(X_train_pca_s, y_train);
/usr/local/lib/python3.10/site-packages/joblib/externals/loky/process_executor.py:700: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak.
show_html(pd.DataFrame(knn_gs.cv_results_).loc[:,['params', 'mean_test_score','rank_test_score']].sort_values(by='rank_test_score').head().to_html())
| params | mean_test_score | rank_test_score | |
|---|---|---|---|
| 54 | {'leaf_size': 1, 'metric': 'cosine', 'n_neighbors': 6, 'weights': 'distance'} | 0.973194 | 1 |
| 252 | {'leaf_size': 20, 'metric': 'cosine', 'n_neighbors': 6, 'weights': 'distance'} | 0.973194 | 1 |
| 186 | {'leaf_size': 10, 'metric': 'cosine', 'n_neighbors': 6, 'weights': 'distance'} | 0.973194 | 1 |
| 120 | {'leaf_size': 5, 'metric': 'cosine', 'n_neighbors': 6, 'weights': 'distance'} | 0.973194 | 1 |
| 318 | {'leaf_size': 25, 'metric': 'cosine', 'n_neighbors': 6, 'weights': 'distance'} | 0.973194 | 1 |
print(classification_report(knn_gs.predict(X_test_pca_s), y_test,target_names=clases))
precision recall f1-score support
4 0.98 0.99 0.98 246
7 0.98 0.98 0.98 250
9 0.98 0.96 0.97 259
accuracy 0.98 755
macro avg 0.98 0.98 0.98 755
weighted avg 0.98 0.98 0.98 755
Vemos que al aplicar la reducción, el modelo de KNN funciona un 0.01 mejor, no es ningun cambio significativo, pero hemos conseguido mejorar un poco el modelo, teniendo todas la relaciones precision-recall superiores a las que teníamos antes. Vemos que para la clase del 4, no se confunde con el 7.
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(knn_gs, X_test_pca_s, y_test, display_labels=clases, ax=plt.subplot());
plt.figure(figsize=(8,8));
roc_auc(knn_gs, X_train_pca_s, y_train, X_test_pca_s, y_test);
Como podemos ver obtenenemos un AUC perfecta para todas las clases. Por lo tanto, para cualesquiera clase, tenemos un 100% de predicciones correctas.
X_train_bin = Binarizer(threshold=0.5).transform(X_train_copia)
X_test_bin = Binarizer(threshold=0.5).transform(X_test_copia)
X_train_bin.shape, X_test_bin.shape
((4514, 784), (755, 784))
X_train_bin = pd.DataFrame(X_train_bin)
X_test_bin = pd.DataFrame(X_test_bin)
X_train_bin.shape, X_test_bin.shape
X_train_bin_2 = X_train_bin.copy()
X_test_bin_2 = X_test_bin.copy()
X_train_standarized_bin = X_train_bin_2.copy()
X_test_standarized_bin = X_test_bin_2.copy()
myPCA = PCA().fit(X_train_standarized_bin[data_columns]);
transformed_train_bin = myPCA.transform(X_train_standarized_bin[X_train_bin_2.columns])
transformed_test_bin = myPCA.transform(X_test_standarized_bin[X_test_bin_2.columns])
nc = 30
X_train_pca_todas_bin = scaler.fit_transform(transformed_train_bin[:,:])
X_train_pca_s_bin = scaler.fit_transform(transformed_train_bin[:,:nc])
X_test_pca_s_bin = scaler.transform(transformed_test_bin[:,:nc])
knn = KNeighborsClassifier()
print(np.mean(cross_val_score(knn, X_train_pca_todas_bin, y_train, cv=10)))
print(np.mean(cross_val_score(knn, X_train_pca_s_bin, y_train, cv=10)))
0.7826923454270746 0.9632301866059689
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
np.cumsum(myPCA.explained_variance_ratio_),
c='red',marker='.',
label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
plt.axhline(y=0.85, color='g', linestyle='-')
<matplotlib.lines.Line2D at 0x1493dc6a0>
# NB Bernoulli k components matriu sense binaritzar
_list = []
for i in range(1, X_train_pca_s_bin.shape[1]+1):
score = cross_val_score(knn, X_train_pca_s_bin[:,:i], y_train, cv=10).mean()
print(i, score)
_list.append(score)
plt.plot(_list, '-o')
plt.xlabel('Número de componentes principales')
plt.ylabel('cross-validation score')
plt.title('Clasificación')
plt.xticks(np.arange(X_train_pca_s_bin.shape[1]), np.arange(1, X_train_pca_s_bin.shape[1]+1))
plt.axhline(y = np.mean(cross_val_score(knn,X_train_pca_s_bin,y_train,cv=10)), color='g', linestyle='-');
1 0.43088466142103093 2 0.5573744677511134 3 0.7396969369935051 4 0.7802317367501913 5 0.8453608500284518 6 0.856890783509605 7 0.8723863391087653 8 0.8914369248278163 9 0.9082814983419343 10 0.9295459450974235 11 0.9315434727154995 12 0.9426167023134429 13 0.9430621235013638 14 0.9477140278241076 15 0.9499303416203911 16 0.9457218962776917 17 0.9499308321723603 18 0.9497086121303691 19 0.9525886427408121 20 0.9501501089025371 21 0.9539165669210995 22 0.9525886427408119 23 0.9550296293389321 24 0.9579081882934679 25 0.9568000313953261 26 0.9585728862115653 27 0.9574676726252379 28 0.9596820242136452 29 0.9621185958440439 30 0.9632301866059689
Vemos que usando 30 componentes nos es suficiente para alanzar una buen cross-validation score
param = {'n_neighbors':[1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 15],
'weights':['distance', 'uniform'],
'leaf_size':[1, 5, 10, 20, 25, 30],
'metric': ['l2', 'l1', 'cosine']}
knn_gs = GridSearchCV(knn,param,cv=10, n_jobs=-1)
knn_gs.fit(X_train_pca_s_bin, y_train);
show_html(pd.DataFrame(knn_gs.cv_results_).loc[:,['params', 'mean_test_score','rank_test_score']].sort_values(by='rank_test_score').head().to_html())
| params | mean_test_score | rank_test_score | |
|---|---|---|---|
| 210 | {'leaf_size': 20, 'metric': 'l2', 'n_neighbors': 7, 'weights': 'distance'} | 0.966107 | 1 |
| 78 | {'leaf_size': 5, 'metric': 'l2', 'n_neighbors': 7, 'weights': 'distance'} | 0.966107 | 1 |
| 342 | {'leaf_size': 30, 'metric': 'l2', 'n_neighbors': 7, 'weights': 'distance'} | 0.966107 | 1 |
| 144 | {'leaf_size': 10, 'metric': 'l2', 'n_neighbors': 7, 'weights': 'distance'} | 0.966107 | 1 |
| 12 | {'leaf_size': 1, 'metric': 'l2', 'n_neighbors': 7, 'weights': 'distance'} | 0.966107 | 1 |
print(classification_report(knn_gs.predict(X_test_pca_s_bin), y_test,target_names=clases))
precision recall f1-score support
4 0.97 0.98 0.98 248
7 0.98 0.96 0.97 255
9 0.95 0.96 0.95 252
accuracy 0.96 755
macro avg 0.96 0.96 0.96 755
weighted avg 0.96 0.96 0.96 755
Apenas hay diferencias de este modelo con el mismo que habíamos relalizado anteriormente. Solo diferencias no sustanciales en el mean_test_score, puesto que este ha disminuido un poco.
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(knn_gs, X_test_pca_s_bin, y_test, display_labels=clases, ax=plt.subplot());
plt.figure(figsize=(8,8));
roc_auc(knn_gs, X_train_pca_s_bin, y_train, X_test_pca_s_bin, y_test);
Usar Naïve Bayes Gausiano con un cierto número de componentes es mucho más adecuado que usar cualesquiera de los modelos de KNN con la transformación que les hemos aplicado. Esto es así ya que la relación de calidad/tiempo de los modelos de KNN comparada con los modelos de NB es mucho peor. Para conseguir una buena calidad en KNN necesitamos mucho más tiempo que para los modelos de NB auqnue estos tengas una accuracy inferior. Aún así, vemos que estos el modelo de NB Gausiano, al escoger un cierto número de componentes con respecto a cuando cogíamos todas las componentes ha mejorado, y por otro lado, la acuracy del modelo de NB Bernoulli ha disminuido.
Determinar el número de componentes es crucial ya que al usar PCA para la reducción de dimensionalidad, hemos de determinar con acierto el número de dimensiones (la proporción de la varianza original) que queremos dejar en los datos.
Si no reducimos la dimensionalidad lo suficiente, no filtraremos el ruido y pasará que a medida que añadimos compoentes en NB Gausiano tendremos un peor score. Por otro lado, si eliminamos demasiadas dimensiones, corremos el riesgo de eliminar información valiosa, como sucede en NB Bernoulli.
Usar KNN con esta transformación es más asequible, pero no nos hará tener un clasificador de códigos postales bueno para una predicción en tiempo real ya que es demasiado costoso, aunque haga un 100% de predicciones correctas. Usar un NB que no nos de esta fiabilidad pero si rapidez, nos hace más eficientes.
Vemos que a NB Gausiano a medida que augmentamos el número de componentes solo empeora, ya que tenemos píxeles que están en cierta forma correlacionados y no son independientes. Al tener esta cantidad de features, podríamos probar de usar una SVM pero alomejor nos cuesta encontrar un poco el kernel correcto, podemos apostar por uno no-lineal, ya que al ver el resultado que nos ha dado el t-SNE, podemos intuir que entre nuestros datos tenemos no-linealidades.
Comprobación aquí: SVM al subconjunto MNIST
Vemos que trabajando con los datos transformados, i.e con menor dimensionalidad, el hecho de poder ajustar los modelos KNN se vuelve más practicable para este caso práctico ya que el tiempo de ejecución se ha reducido considerablemente y la precisión no se ha visto perjudicada, por lo tanto vemos que reduciendo la dimensionalidad hace que los modelos KNN funcionen de forma más eficiente y manteniendo la calidad que tenían cuando usábamos todos los píxeles de las imágenes. Vemos que solamente usando 30 componentes tenemos suficente para llegar a la misma calidad que cúando usábamos las 784.
Por otro lado, también vemos que transformando los datos, después de la aplicación del PCA y quedándonos solo con 30 componentes la accuracy del modelo de NB Gausiano ha mejorado de forma significativa, pasando de un 0.57 a un 0.68. A medida que ibámos añadiendo más componentes podíamos ver que la $R^{2}$ del conjunto de validación disminuia. Esto se debe a que en realidad la asunción de que los píxeles son independientes no es corercta, ya que algunos si que estan altamente correlacionadas y no son independientes. Además el PCA tampoco nos ha funcionado demasiado ya que pondera cada pixel por igual y no tiene en cuenta la clase.
Además un inconveniente es que para el modelo de NB Bernouilli, ha sido arriesgado realizar esta reducción de dimensionalidad, ya que hemos perdido información valiosa y nos ha derivado en un peor clasificador.
En general pero, trabajamos con menos dimensiones, y esto siempre nos viene bien ya que el tiempo de cómputo va a dismuinir, y también la practicabilidad a la hora de gestionar un recurso como es la memoria donde cargaremos el modelo.
Para razonar qué modelo de entre los cuatro escogeria para reconocer los códigos postales que se encuentran cartas, tendré en cuenta varios factores que me parecen cruciales para la elección.
Para saber cuáles son factores, hemos de retroceder al enunciado y fijarnos en el hecho de que se nos dice de forma indirecta que queremos:
Por lo tanto, nuestra elección del modelo estará estrechamente condicionada por los dos factores de arriba. Así pues, tendremos que escoger un modelo que tenga un equilibrio de ambos, es decir, que no tarde mucho en dar la clasificación y que lo haga relativamente bien, es decir que nos podamos fiar de la clasificación que hace de los códigos para todas las cartas.
Lo que hemos de interpretar del enunciado es que lo que realmente queremos es dar una predicción en tiempo real de los códigos postales para clasificar las cartas que nos lleguen. Esta predicción en tiempo real, ha de ser lo más rápida y fiable posible.
Hemos visto que los distintos modelos tienen una $R^{2}$ distinta, podemos verlas como siguen:
Además estas $R^{2}$ se han obtenido sin hacer aún la reducción de la dimensionalidad para posteriormente pasarlo a los modelos, es decir sin usar los componentes de PCA para reducir las dimensiones y ver como ha afectado a la calidad del resultado.
Como podemos ver hay una gran diferencia entre las $R^{2}$ del modelo de Naïve Bayes Gausiano y el resto de modelos.
Una vez realizada la transformación, hemos elegido un número de componentes, nc=30 y hemos obtenido las matrices de datos transformadas. Una vez ajustados los nuevos modelos, tenemos las $R^{2}$, como siguen:
Además también hay una diferencia considerable entre el tiempo de ejecución entre los modelos de Naïve Bayes y los KNN
Tenemos por un lado que el tiempo de ejecución de los Naïve Bayes es $\Theta(1)$ mientras que lo mejor que lo pueden hacer los modelos de KNN basados en KDTree es $\Theta(log(N))$, siendo N el numero de data points que tengamos. Por lo tanto como más grande sea el tamaño de los datos aplicar un KNN se vuelve un poco impracticable si no le aplicamos alguna reducción o alguna tuneada importante en los hiperparámetros.
Por lo tanto, los modelos KNN funcionan mejor cuando los datos son pequeños, pero si sabemos que el tamaño de nuestros datos es grande o va aumentando, seria aconsejable elegir unos modelos de Naive Bayes.
Aunque, KNN a veces puede ser una buena opción en algunos entornos, especialmente si los datos que tenemos tiene baja dimensión o si les aplicamos una reducción de dimensionalidad, vemos que usar KNN para clasificación de imágenes es un poco impracticable, por el tiempo de ejecución, ya que por el contrario son los modelos que mejor fiabilidad tienen, ya que producen mejores resultados que Naïve Bayes. Pero el problema es que las imágenes suelen tener grandes dimensiones, i.e pueden contener muchos píxeles.
Por lo tanto, hemos visto que sin aplicar la transformación a los datos, quedarnos con alguno de los modelos de KNN seria inviable ya que el tiempo de ejecución de estos no nos permitiria poder clasificar los códigos postales de las cartas de forma rápida, aunque si de forma muy fiable.
Dada esta situación, y después de aplicar la transformación del PCA a las matrices de datos, y quedándonos con solo 30 componentes, hemos podido ver que el tiempo de ejecución de los modelos KNN es menor, aunque sigue siendo demasiado alta en comparación con los modelos de Naïve Bayes.
Es por esto que creo que la mejor opción seria tener como clasificador al modelo de NB Bernoulli sin la reducción de dimensionalidad. Este modelo funciona mejor que el Naïve Bayes en ambos casos(sin y con transformación) además en tiempo de ejecución va a la par que el modelo de NB Gausiano. El ~10% más de acuracy que nos dan los modelos KNN con respecto a este, no nos compensa, ya que debemos ser eficientes a la hora de clasificar las cartas, puesto que no seria rentable clasificar menos cartas pero de forma segura a, más cartas, y con solo un ~10% de clasificaciones erróneas. El servicio de correos preferiria asumir este coste extra surgido de la mala clasifiación a ser menos eficiente en tiempo.
Si el servicio de correos estuviese dispuesto a asumir un coste un poco superior, alomejor podria plantearse usar el método de KNN con la matriz sin binarizar y con la reducción de la dimensionalidad.